gifs/api

Paddy 2014-10-17 Parent:08ec88016e2f Child:eb450538f079

4:1bbbe113f599 Go to Latest

gifs/api/usage.go

Upload is no longer async, memstorage is parallel-safe. Upload no longer needs to be run async (it can be run inside a goroutine), so it now returns stuff instead of taking a channel as an argument. This will make it easier to implement, as all the async stuff is an abstraction above, and therefore doesn't need to be worried about for each reimplementation. The memstorage type is no longer exported and can now be safely used by multiple goroutines, thanks to the sync package.

History
1 package api
3 import (
4 "sync"
5 )
7 func NewUsageTracker() *UsageTracker {
8 return &UsageTracker{
9 usages: make(map[string]*Usage),
10 }
11 }
13 type UsageTracker struct {
14 usages map[string]*Usage
15 sync.Mutex
16 }
18 func (u *UsageTracker) TrackUploads(id string) (bytes, requests chan int64) {
19 u.Lock()
20 defer u.Unlock()
21 if _, ok := u.usages[id]; !ok {
22 u.usages[id] = &Usage{
23 UploadBytesChan: make(chan int64),
24 DownloadBytesChan: make(chan int64),
25 UploadRequestsChan: make(chan int64),
26 DownloadRequestsChan: make(chan int64),
27 }
28 go u.usages[id].collect()
29 }
30 return u.usages[id].UploadBytesChan, u.usages[id].UploadRequestsChan
31 }
33 func (u *UsageTracker) TrackDownloads(id string) (bytes, requests chan int64) {
34 u.Lock()
35 defer u.Unlock()
36 if _, ok := u.usages[id]; !ok {
37 u.usages[id] = &Usage{
38 UploadBytesChan: make(chan int64),
39 DownloadBytesChan: make(chan int64),
40 UploadRequestsChan: make(chan int64),
41 DownloadRequestsChan: make(chan int64),
42 }
43 go u.usages[id].collect()
44 }
45 return u.usages[id].DownloadBytesChan, u.usages[id].DownloadRequestsChan
46 }
48 type Usage struct {
49 UploadedBytes int64
50 UploadBytesChan chan int64
51 DownloadedBytes int64
52 DownloadBytesChan chan int64
53 UploadRequests int64
54 UploadRequestsChan chan int64
55 DownloadRequests int64
56 DownloadRequestsChan chan int64
57 }
59 func (u *Usage) collect() {
60 for {
61 select {
62 case b, ok := <-u.UploadBytesChan:
63 if !ok {
64 u.UploadBytesChan = nil
65 }
66 u.UploadedBytes += b
67 case r, ok := <-u.UploadRequestsChan:
68 if !ok {
69 u.UploadRequestsChan = nil
70 }
71 u.UploadRequests += r
72 case b, ok := <-u.DownloadBytesChan:
73 if !ok {
74 u.DownloadBytesChan = nil
75 }
76 u.DownloadedBytes += b
77 case r, ok := <-u.DownloadRequestsChan:
78 if !ok {
79 u.DownloadRequestsChan = nil
80 }
81 u.DownloadRequests += r
82 }
83 if u.UploadBytesChan == nil && u.UploadRequestsChan == nil && u.DownloadBytesChan == nil && u.DownloadRequestsChan == nil {
84 break
85 }
86 }
87 }