Actor
It is a highly concurrent processing model, each Actor
has its own state ordered message processing mechanism, so in the case of business process does not need to develop mechanisms for the lock, so as to achieve more efficient processing possibilities. XRPC
Is a call-based remote interface RPC
components, it can easily achieve high-performance remote interface calls; XRPC
when you create a remote interface that supports the creation of an interface for the corresponding Actor
instance. When you create an interface Actor
, the Client for all cases of this example Actor
is an orderly process all method calls. The following describes how to XRPC
create and useActor
What applies to the sceneActor
Since each Actor
has its own status and order processing mechanism, that can be deployed for these advantages related business; the table in the chess game may be a Actor
ticket where each car can be a Actor
spike in every It is a kind of commodity Actor
. Among these Actor
are the orderly conduct of all operations, there is no lock, no need transactions (to protect by EventSourcing) and does not produce deadlock; change the whole data memory operations, can greatly improve the processing performance of the business through this.
Reference XRPC
Install-Package BeetleX.XRPC
The definition Actor
of RPC service
XRPC support Actor
services are built on EventNext
top of its benefits is a direct interface behaviors Actor
create, rather than the traditional method for receiving a message plus, so call in the application design and also very convenient and flexible. Next, define a simple Actor
service
- Interface definition
1 public interface IAmountService 2 { 3 Task<int> Income(int amount); 4 Task<int> Payout(int amount); 5 Task<int> Get(); 6 }
-
Implement an interface
1 [Service(typeof(IAmountService))] 2 public class AmountService : ActorState, IAmountService 3 { 4 5 private int mAmount; 6 7 public override Task ActorInit(string id) 8 { 9 return base.ActorInit(id); 10 } 11 12 public Task<int> Get() 13 { 14 return mAmount.ToTask(); 15 } 16 17 public Task<int> Income(int amount) 18 { 19 mAmount += amount; 20 return mAmount.ToTask(); 21 } 22 23 public Task<int> Payout(int amount) 24 { 25 mAmount -= amount; 26 return mAmount.ToTask(); 27 } 28 }
-
Start the corresponding RPC service
private static XRPCServer mXRPCServer; static void Main(string[] args) { mXRPCServer = new XRPCServer(); mXRPCServer.ServerOptions.LogLevel = LogType.Error; mXRPCServer.Register(typeof(Program).Assembly); mXRPCServer.Open(); Console.Read(); }
The code above is the default port
9090
binding on theRPC
service, you can view the log service starts by running case
Create a remote Actor
call
- Creating RPC Client
1 client = new XRPCClient("192.168.2.18", 9090); 2 client.Connect();
RPC
client through whichCreate
you can create interface agent - Actor instance to create interfaces
IAmountService henry = client.Create<IAmountService>("henry"); IAmountService ken = client.Create<IAmountService>("ken");
IAmountService
creation of twoActor
objects, the operation of these two objects are isolated from each other without disturbing each other; eachActor
method objects are ordered in concurrent execution, does not produce thread-safety issues, so in different ways the operation of the image data members do not need locks to ensure data security.
test
In order to verify Actor
the safety of isolation and concurrency, simply concurrent test
1 for (int i = 0; i < concurrent; i++) 2 { 3 var task = Task.Run(async () => 4 { 5 for (int k = 0; k < requests; k++) 6 { 7 await henry.Income(10); 8 System.Threading.Interlocked.Increment(ref mCount); 9 } 10 }); 11 tasks.Add(task); 12 task = Task.Run(async () => 13 { 14 for (int k = 0; k < requests; k++) 15 { 16 await henry.Payout(10); 17 System.Threading.Interlocked.Increment(ref mCount); 18 } 19 }); 20 tasks.Add(task); 21 task = Task.Run(async () => 22 { 23 for (int k = 0; k < requests; k++) 24 { 25 await ken.Income(10); 26 System.Threading.Interlocked.Increment(ref mCount); 27 } 28 }); 29 tasks.Add(task); 30 task = Task.Run(async () => 31 { 32 for (int k = 0; k < requests; k++) 33 { 34 await ken.Payout(10); 35 System.Threading.Interlocked.Increment(ref mCount); 36 } 37 }); 38 tasks.Add(task); 39 } 40 await Task.WhenAll(tasks.ToArray()); 41 double useTime = EventCenter.Watch.ElapsedMilliseconds - start; 42 Console.WriteLine($"Completed count:{mCount}|use time:{useTime}|rps:{(mCount / useTime * 1000d):###.00} |henry:{await henry.Get()},ken:{await ken.Get()}");
Two programs simultaneously in the machine to run a bit, in the case of 50 concurrent about 110,000 RPS
Services in Actor
isolation
Service interface is instantiated by different names Actor
, the same service even more than Client
the same time a name Actor
created service can guarantee its uniqueness.