Решение на Concurrent Tasks от Георги Павлов

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

Към профила на Георги Павлов

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 6 успешни тест(а)
  • 7 неуспешни тест(а)

Код

package main
import (
"fmt"
"sync"
"time"
)
type Task interface {
Execute(int) (int, error)
}
// 1. Pipeline
type Pipe struct {
tasks []Task
}
func (p *Pipe) Execute(i int) (int, error) {
if len(p.tasks) == 0 {
return 0, fmt.Errorf("Pipelord is not pleased with your lack of tasks!")
}
result := i
var err error
for _, task := range p.tasks {
if result, err = task.Execute(result); err != nil {
return 0, err
}
}
return result, err
}
func Pipeline(tasks ...Task) Task {
t := &Pipe{}
t.tasks = tasks
return t
}
// 2. Fast
type Fast struct {
tasks []Task
}
type channelResult struct {
err error
result int
}
func (f *Fast) Execute(i int) (int, error) {
if len(f.tasks) == 0 {
return 0, fmt.Errorf("Fastlord is not pleased with your lack of tasks!")
}
c := make(chan *channelResult)
var once sync.Once
for _, task := range f.tasks {
go func(task Task) {
result, err := task.Execute(i)
once.Do(func() {
c <- &channelResult{result: result, err: err}
})
}(task)
}
cr := <-c
return cr.result, cr.err
}
func Fastest(tasks ...Task) Task {
return &Fast{tasks}
}
// 3. Timed
type Timey struct {
task Task
timeout time.Duration
}
func (t *Timey) Execute(i int) (int, error) {
c := make(chan *channelResult)
go func(task Task) {
result, err := task.Execute(i)
c <- &channelResult{result: result, err: err}
}(t.task)
select {
case cr := <-c:
return cr.result, cr.err
case <-time.After(t.timeout):
return 0, fmt.Errorf("Timelord is not pleased with your dallying!")
}
}
func Timed(task Task, timeout time.Duration) Task {
return &Timey{task, timeout}
}
// 4. ConcurentMapReduce
type MapReduce struct {
tasks []Task
reduce func(results []int) int
}
func (mr *MapReduce) Execute(i int) (int, error) {
if len(mr.tasks) == 0 {
return 0, fmt.Errorf("Maplord is not reduced by your lack of tasks!")
}
return 0, nil
}
func ConcurrentMapReduce(reduce func(results []int) int, tasks ...Task) Task {
return &MapReduce{tasks, reduce}
}
type GreatestSearch struct {
errorLimit int
tasks <-chan Task
}
func GreatestSearcher(errorLimit int, tasks <-chan Task) Task {
return &GreatestSearch{errorLimit, tasks}
}
func (gs *GreatestSearch) Execute(i int) (int, error) {
return 0, nil
}

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

PASS
ok  	_/tmp/d20161129-30451-1ifqfgp	0.003s
PASS
ok  	_/tmp/d20161129-30451-1ifqfgp	0.003s
PASS
ok  	_/tmp/d20161129-30451-1ifqfgp	0.003s
PASS
ok  	_/tmp/d20161129-30451-1ifqfgp	0.103s
PASS
ok  	_/tmp/d20161129-30451-1ifqfgp	0.203s
PASS
ok  	_/tmp/d20161129-30451-1ifqfgp	0.134s
--- FAIL: TestTimedDoesntLeaveGoroutineHanging (0.20s)
	solution_test.go:216: Expected that there will be as many goroutines as at the start(3) after Timed task has finished after it has timeouted but got 4
		
		BEFORE:
		goroutine profile: total 2
		1 @ 0x42a8aa 0x42a99e 0x40464f 0x404365 0x46c406 0x46f47d 0x46c0a1 0x46d115 0x46c735 0x401276 0x42a444 0x459f01
		#	0x46c405	testing.(*T).Run+0x315		/usr/local/go/src/testing/testing.go:647
		#	0x46f47c	testing.RunTests.func1+0x6c	/usr/local/go/src/testing/testing.go:793
		#	0x46c0a0	testing.tRunner+0x80		/usr/local/go/src/testing/testing.go:610
		#	0x46d114	testing.RunTests+0x2f4		/usr/local/go/src/testing/testing.go:799
		#	0x46c734	testing.(*M).Run+0x84		/usr/local/go/src/testing/testing.go:743
		#	0x401275	main.main+0xc5			_/tmp/d20161129-30451-1ifqfgp/_test/_testmain.go:78
		#	0x42a443	runtime.main+0x1f3		/usr/local/go/src/runtime/proc.go:183
		
		1 @ 0x4c1fef 0x4c1df0 0x4beaa1 0x472f53 0x46c0a1 0x459f01
		#	0x4c1fee	runtime/pprof.writeRuntimeProfile+0x9e						/usr/local/go/src/runtime/pprof/pprof.go:614
		#	0x4c1def	runtime/pprof.writeGoroutine+0x9f						/usr/local/go/src/runtime/pprof/pprof.go:576
		#	0x4beaa0	runtime/pprof.(*Profile).WriteTo+0x340						/usr/local/go/src/runtime/pprof/pprof.go:298
		#	0x472f52	_/tmp/d20161129-30451-1ifqfgp.TestTimedDoesntLeaveGoroutineHanging+0x172	/tmp/d20161129-30451-1ifqfgp/solution_test.go:191
		#	0x46c0a0	testing.tRunner+0x80								/usr/local/go/src/testing/testing.go:610
		
		
		
		AFTER:
		goroutine profile: total 4
		1 @ 0x42a8aa 0x42a99e 0x4039a8 0x40376d 0x474fd4 0x459f01
		#	0x474fd3	_/tmp/d20161129-30451-1ifqfgp.(*Timey).Execute.func1+0xc3	/tmp/d20161129-30451-1ifqfgp/solution.go:84
		
		1 @ 0x42a8aa 0x42a99e 0x40464f 0x404365 0x46c406 0x46f47d 0x46c0a1 0x46d115 0x46c735 0x401276 0x42a444 0x459f01
		#	0x46c405	testing.(*T).Run+0x315		/usr/local/go/src/testing/testing.go:647
		#	0x46f47c	testing.RunTests.func1+0x6c	/usr/local/go/src/testing/testing.go:793
		#	0x46c0a0	testing.tRunner+0x80		/usr/local/go/src/testing/testing.go:610
		#	0x46d114	testing.RunTests+0x2f4		/usr/local/go/src/testing/testing.go:799
		#	0x46c734	testing.(*M).Run+0x84		/usr/local/go/src/testing/testing.go:743
		#	0x401275	main.main+0xc5			_/tmp/d20161129-30451-1ifqfgp/_test/_testmain.go:78
		#	0x42a443	runtime.main+0x1f3		/usr/local/go/src/runtime/proc.go:183
		
		1 @ 0x42a8aa 0x42a99e 0x40464f 0x404365 0x4730b5 0x46c0a1 0x459f01
		#	0x4730b4	_/tmp/d20161129-30451-1ifqfgp.TestTimedDoesntLeaveGoroutineHanging+0x2d4	/tmp/d20161129-30451-1ifqfgp/solution_test.go:225
		#	0x46c0a0	testing.tRunner+0x80								/usr/local/go/src/testing/testing.go:610
		
		1 @ 0x4c1fef 0x4c1df0 0x4beaa1 0x475941 0x459f01
		#	0x4c1fee	runtime/pprof.writeRuntimeProfile+0x9e						/usr/local/go/src/runtime/pprof/pprof.go:614
		#	0x4c1def	runtime/pprof.writeGoroutine+0x9f						/usr/local/go/src/runtime/pprof/pprof.go:576
		#	0x4beaa0	runtime/pprof.(*Profile).WriteTo+0x340						/usr/local/go/src/runtime/pprof/pprof.go:298
		#	0x475940	_/tmp/d20161129-30451-1ifqfgp.TestTimedDoesntLeaveGoroutineHanging.func2+0x1a0	/tmp/d20161129-30451-1ifqfgp/solution_test.go:212
		
		
FAIL
exit status 1
FAIL	_/tmp/d20161129-30451-1ifqfgp	0.204s
--- FAIL: TestConcurrentMapReduceFails (0.00s)
	solution_test.go:244: Expected error did not occur instead got 0
FAIL
exit status 1
FAIL	_/tmp/d20161129-30451-1ifqfgp	0.003s
--- FAIL: TestConcurrentMapReduceSimple (0.00s)
	solution_test.go:253: Expected result to be 55 but is 0
FAIL
exit status 1
FAIL	_/tmp/d20161129-30451-1ifqfgp	0.004s
--- FAIL: TestGreatestSearcherSimple (0.00s)
	solution_test.go:289: Received result 0 when expecting 2
FAIL
exit status 1
FAIL	_/tmp/d20161129-30451-1ifqfgp	0.003s
--- FAIL: TestGreatestSearcherComplex (0.00s)
	solution_test.go:302: Received result 0 when expecting 42
FAIL
exit status 1
FAIL	_/tmp/d20161129-30451-1ifqfgp	0.003s
--- FAIL: TestGreatestSearcherErrors (0.00s)
    --- FAIL: TestGreatestSearcherErrors/like_the_example (0.00s)
    	solution_test.go:313: Expected error did not occur instead got 0
    --- FAIL: TestGreatestSearcherErrors/close_immediately (0.00s)
    	solution_test.go:322: Expected error did not occur instead got 0
    --- FAIL: TestGreatestSearcherErrors/only_failure (0.00s)
    	solution_test.go:335: Expected error did not occur instead got 0
FAIL
exit status 1
FAIL	_/tmp/d20161129-30451-1ifqfgp	0.003s
--- FAIL: TestThemAll (0.02s)
	solution_test.go:380: Received 0 when expecting 75
FAIL
exit status 1
FAIL	_/tmp/d20161129-30451-1ifqfgp	0.023s

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

Георги обнови решението на 29.11.2016 03:48 (преди над 1 година)

+package main
+
+import (
+ "fmt"
+ "sync"
+ "time"
+)
+
+type Task interface {
+ Execute(int) (int, error)
+}
+
+// 1. Pipeline
+
+type Pipe struct {
+ tasks []Task
+}
+
+func (p *Pipe) Execute(i int) (int, error) {
+ if len(p.tasks) == 0 {
+ return 0, fmt.Errorf("Pipelord is not pleased with your lack of tasks!")
+ }
+ result := i
+ var err error
+ for _, task := range p.tasks {
+ if result, err = task.Execute(result); err != nil {
+ return 0, err
+ }
+ }
+ return result, err
+}
+
+func Pipeline(tasks ...Task) Task {
+ t := &Pipe{}
+ t.tasks = tasks
+ return t
+}
+
+// 2. Fast
+
+type Fast struct {
+ tasks []Task
+}
+
+type channelResult struct {
+ err error
+ result int
+}
+
+func (f *Fast) Execute(i int) (int, error) {
+ if len(f.tasks) == 0 {
+ return 0, fmt.Errorf("Fastlord is not pleased with your lack of tasks!")
+ }
+ c := make(chan *channelResult)
+ var once sync.Once
+
+ for _, task := range f.tasks {
+ go func(task Task) {
+ result, err := task.Execute(i)
+ once.Do(func() {
+ c <- &channelResult{result: result, err: err}
+ })
+ }(task)
+ }
+ cr := <-c
+ return cr.result, cr.err
+}
+
+func Fastest(tasks ...Task) Task {
+ return &Fast{tasks}
+}
+
+// 3. Timed
+
+type Timey struct {
+ task Task
+ timeout time.Duration
+}
+
+func (t *Timey) Execute(i int) (int, error) {
+ c := make(chan *channelResult)
+ go func(task Task) {
+ result, err := task.Execute(i)
+ c <- &channelResult{result: result, err: err}
+ }(t.task)
+
+ select {
+ case cr := <-c:
+ return cr.result, cr.err
+ case <-time.After(t.timeout):
+ return 0, fmt.Errorf("Timelord is not pleased with your dallying!")
+ }
+}
+
+func Timed(task Task, timeout time.Duration) Task {
+ return &Timey{task, timeout}
+}
+
+// 4. ConcurentMapReduce
+
+type MapReduce struct {
+ tasks []Task
+ reduce func(results []int) int
+}
+
+func (mr *MapReduce) Execute(i int) (int, error) {
+ if len(mr.tasks) == 0 {
+ return 0, fmt.Errorf("Maplord is not reduced by your lack of tasks!")
+ }
+ return 0, nil
+}
+
+func ConcurrentMapReduce(reduce func(results []int) int, tasks ...Task) Task {
+ return &MapReduce{tasks, reduce}
+}
+
+type GreatestSearch struct {
+ errorLimit int
+ tasks <-chan Task
+}
+
+func GreatestSearcher(errorLimit int, tasks <-chan Task) Task {
+ return &GreatestSearch{errorLimit, tasks}
+}
+
+func (gs *GreatestSearch) Execute(i int) (int, error) {
+ return 0, nil
+}