Решение на HTTP сваляч от Ралица Великова

Обратно към всички решения

Към профила на Ралица Великова

Резултати

  • 8 точки от тестове
  • 0 бонус точки
  • 8 точки общо
  • 10 успешни тест(а)
  • 3 неуспешни тест(а)

Код

package main
import (
"container/ring"
//"sync"
)
type Request interface {
ID() string
Run() (result interface{}, err error)
Cacheable() bool
SetResult(result interface{}, err error)
}
type Requester interface {
AddRequest(request Request)
Stop()
}
const (
Working = iota
Stopped
)
type RequestHandler struct {
requests chan Request
working int
sem chan struct{}
cache *ring.Ring
running map[string]bool
// waitgroup sync.WaitGroup
}
type CacheElement struct {
Id string
Result interface{}
Err error
}
func NewRequester(cacheSize int, throttleSize int) Requester {
requestChannel := make(chan Request)
cache := ring.New(cacheSize)
running := make(map[string]bool)
requester := RequestHandler{requests: requestChannel, working: Working, cache: cache, running: running}
requester.sem = make(chan struct{})
//requester.waitgroup.Add(throttleSize)
go func() {
for request := range requester.requests {
ready := false
requester.cache.Do(func(cacheElement interface{}) {
element, _ := cacheElement.(CacheElement)
if element.Id == request.ID() {
request.SetResult(element.Result, element.Err)
ready = true
}
})
if ready {
continue
}
if requester.running[request.ID()] {
go func() {
requester.requests <- request
}()
continue
}
requester.running[request.ID()] = true
result, err := request.Run()
requester.running[request.ID()] = false
if request.Cacheable() {
requester.cache = requester.cache.Next()
cacheElement := CacheElement{}
cacheElement.Id = request.ID()
cacheElement.Result, cacheElement.Err = result, err
requester.cache.Value = cacheElement
}
}
requester.sem <- struct{}{}
}()
return &requester
}
func (r *RequestHandler) AddRequest(request Request) {
if r.working == Working {
r.requests <- request
}
}
func (r *RequestHandler) Stop() {
r.working = Stopped
//requester.waitgroup.Wait()
close(r.requests)
<-r.sem
}

Лог от изпълнението

▸ Покажи лога

История (1 версия и 0 коментара)

Ралица обнови решението на 31.12.2015 19:53 (преди над 2 години)

▸ Покажи разликите
+package main
+
+import (
+ "container/ring"
+ //"sync"
+)
+
+type Request interface {
+ ID() string
+ Run() (result interface{}, err error)
+ Cacheable() bool
+ SetResult(result interface{}, err error)
+}
+
+type Requester interface {
+ AddRequest(request Request)
+ Stop()
+}
+
+const (
+ Working = iota
+ Stopped
+)
+
+type RequestHandler struct {
+ requests chan Request
+ working int
+ sem chan struct{}
+ cache *ring.Ring
+ running map[string]bool
+ // waitgroup sync.WaitGroup
+}
+
+type CacheElement struct {
+ Id string
+ Result interface{}
+ Err error
+}
+
+func NewRequester(cacheSize int, throttleSize int) Requester {
+ requestChannel := make(chan Request)
+ cache := ring.New(cacheSize)
+ running := make(map[string]bool)
+
+ requester := RequestHandler{requests: requestChannel, working: Working, cache: cache, running: running}
+
+ requester.sem = make(chan struct{})
+
+ //requester.waitgroup.Add(throttleSize)
+
+ go func() {
+ for request := range requester.requests {
+
+ ready := false
+
+ requester.cache.Do(func(cacheElement interface{}) {
+ element, _ := cacheElement.(CacheElement)
+
+ if element.Id == request.ID() {
+ request.SetResult(element.Result, element.Err)
+ ready = true
+ }
+ })
+
+ if ready {
+ continue
+ }
+
+ if requester.running[request.ID()] {
+ go func() {
+ requester.requests <- request
+ }()
+ continue
+ }
+
+ requester.running[request.ID()] = true
+ result, err := request.Run()
+ requester.running[request.ID()] = false
+
+ if request.Cacheable() {
+ requester.cache = requester.cache.Next()
+
+ cacheElement := CacheElement{}
+ cacheElement.Id = request.ID()
+ cacheElement.Result, cacheElement.Err = result, err
+
+ requester.cache.Value = cacheElement
+ }
+
+ }
+ requester.sem <- struct{}{}
+ }()
+
+ return &requester
+}
+
+func (r *RequestHandler) AddRequest(request Request) {
+ if r.working == Working {
+ r.requests <- request
+ }
+}
+
+func (r *RequestHandler) Stop() {
+ r.working = Stopped
+ //requester.waitgroup.Wait()
+ close(r.requests)
+ <-r.sem
+}