github.com/asynkron/protoactor-go@v0.0.0-20240308120642-ef91a6abee75/cluster/README.MD (about) 1 # Proto.Actor Cluster - Virtual Actors (Alpha) 2 3 ## Massively distributed actors for GO 4 5 Proto.Actor supports the classic actor model also found in Erlang and Akka.<br> 6 Our cluster support however uses a different approach, **Virtual Actor Model**. 7 8 This is a model where each actor appears to *always exist*. 9 There is no lifecycle as in the classic actor model. 10 You get a reference to the actor by asking for it's ID. 11 12 e.g. 13 14 ```go 15 hello := shared.GetHelloGrain("abc") 16 res := hello.SayHello(&shared.HelloRequest{Name: "Proto.Actor"}) 17 ``` 18 19 This will ask the cluster where the 'abc' actor is located. 20 If it does not yet exist, it will be created for you. 21 22 See Microsoft Orleans for more info about the Virtual Actor Model: 23 [http://dotnet.github.io/orleans/](http://dotnet.github.io/orleans/) 24 25 ## How to 26 27 ## Protobuf IDL Definition 28 29 Start by defining your messages and grain contracts. 30 You do this by using Protobuf IDL files. 31 32 Here is the definition from the `/examples/cluster/shared` example 33 34 ```proto 35 syntax = "proto3"; 36 package shared; 37 38 message HelloRequest { 39 string name = 1; 40 } 41 42 message HelloResponse { 43 string message = 1; 44 } 45 46 message AddRequest { 47 double a = 1; 48 double b = 2; 49 } 50 51 message AddResponse { 52 double result = 1; 53 } 54 55 service Hello { 56 rpc SayHello (HelloRequest) returns (HelloResponse) {} 57 rpc Add(AddRequest) returns (AddResponse) {} 58 } 59 ``` 60 61 Once you have this, you can generate your code using the protobuf `protoc` compiler. 62 63 **Windows** 64 65 ```batch 66 #generate messages 67 protoc -I=. -I=%GOPATH%\src --gogoslick_out=. protos.proto 68 #generate grains 69 protoc -I=. -I=%GOPATH%\src --gorleans_out=. protos.proto 70 ``` 71 72 ## Implementing 73 74 Once the messages and contracts have been generated, you can start implementing your own business logic. 75 This is essentially a type which is powered by a Proto.Actor actor behind the scenes. 76 77 ```go 78 package shared 79 80 // a Go struct implementing the Hello interface 81 type hello struct { 82 } 83 84 func (*hello) SayHello(r *HelloRequest) *HelloResponse { 85 return &HelloResponse{Message: "hello " + r.Name} 86 } 87 88 func (*hello) Add(r *AddRequest) *AddResponse { 89 return &AddResponse{Result: r.A + r.B} 90 } 91 92 // Register what implementation Proto.Actor should use when 93 // creating actors for a certain grain type. 94 func init() { 95 // apply DI and setup logic 96 HelloFactory(func() Hello { return &hello{} }) 97 } 98 ``` 99 100 ## Seed nodes 101 102 ```go 103 func main() { 104 cluster.Start("127.0.0.1:7711") 105 console.ReadLine() 106 } 107 ``` 108 109 ## Member nodes 110 111 ```go 112 func main() { 113 cluster.Start("127.0.0.1:0", "127.0.0.1:7711") 114 115 // get a reference to the virtual actor called "abc" of type Hello 116 hello := shared.GetHelloGrain("abc") 117 res := hello.SayHello(&shared.HelloRequest{Name: "Proto.Actor"}) 118 log.Printf("Message from grain %v", res.Message) 119 } 120 ``` 121 122 ## FAQ 123 124 ### Can I use Proto.Actor Cluster in production? 125 126 The Proto.Actor Cluster support is in alpha version, thus not production ready. 127 128 ### What about performance? 129 130 Proto.Actor Remoting is able to pass 1 million+ messages per second on a standard dev machine. 131 This is the same infrastructure used in Proto.Actor cluster. 132 Proto.Actor Cluster however uses an RPC API, meaning it is Request/Response in nature. 133 If you wait for a response for each call, the throughput will ofcourse be a lot less. 134 Async Fire and forget for performance, Request/Response for simplicity.