gifs/api

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

5:b5d88d57d587 Go to Latest

gifs/api/usage.go

Simplify upload. Simplify the upload code by not running the hashing async, which requires fewer copy operations and less channel synchronization. Also, take advantage of the fact that PipeWriters and PipeReaders will return an error to the PipeReaders/PipeWriters (respectively) when read/write is called (respectively) to avoid passing back errors through channels.

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