forked from asynkron/protoactor-go
/
main.go
99 lines (86 loc) · 1.7 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package main
import (
"flag"
"fmt"
"log"
"os"
"runtime"
"runtime/pprof"
"time"
"github.com/AsynkronIT/protoactor-go/actor"
)
type request struct {
num int
size int
div int
}
var (
props = actor.FromProducer(newState).WithMailbox(actor.NewUnboundedLockfreeMailbox())
)
type state struct {
sum int
replies int
replyTo *actor.PID
}
func newState() actor.Actor {
return &state{}
}
func (s *state) Receive(ctx actor.Context) {
switch msg := ctx.Message().(type) {
case *request:
if msg.size == 1 {
ctx.Respond(msg.num)
return
}
s.replies = msg.div
s.replyTo = ctx.Sender()
for i := 0; i < msg.div; i++ {
child := actor.Spawn(props)
child.Request(&request{
num: msg.num + i*(msg.size/msg.div),
size: msg.size / msg.div,
div: msg.div,
}, ctx.Self())
}
case int:
s.sum += msg
s.replies--
if s.replies == 0 {
s.replyTo.Tell(s.sum)
}
}
}
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
var memprofile = flag.String("memprofile", "", "write mem profile to file")
func main() {
flag.Parse()
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}
runtime.GOMAXPROCS(runtime.NumCPU())
runtime.GC()
start := time.Now()
pid := actor.Spawn(props)
res, _ := pid.RequestFuture(&request{
num: 0,
size: 1000000,
div: 10,
}, 10*time.Second).Result()
result := res.(int)
took := time.Since(start)
fmt.Printf("Result: %d in %d ms.\n", result, took.Nanoseconds()/1e6)
if *memprofile != "" {
f, err := os.Create(*memprofile)
if err != nil {
log.Fatal(err)
}
pprof.WriteHeapProfile(f)
f.Close()
return
}
}