async/await continuation in another process

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



async/await continuation in another process



Let's assume we have two processes executing the same code, i.e. both processes have completely the same codebase. The code calls async operation that makes a request over the network to the third process. Is it possible to initiate async operation on process #1 and process the continuation on process #2?


public class ResourcesService : IResourcesService

public async Task<ResourcesData> GetResourcesData()

var cpuUsageData = await Services.GetService<ICpuService>().GetCpuUsageData();

var memoryData = await Services.GetService<IMemoryService>().GetMemoryData();

return new ResourcesData CpuUsageData = cpuUsageData, MemoryData = memoryData ;




Basically, communication is performed via internally developed messaging and both process #1 and process #2 may have access to the results of async operation.



The question is "is it possible to initiate a request to ICpuService.GetCpuUsageData on the process #1 and continue execution on the process #2? i.e. is it possible to break somehow the method to the state machine like async/await does so that the continuation can be resumed on a different process and even on a different server?"





You want to write code in Process A and inject it to run asynchronously in Process B? Unless you write yourself some very weird LINQ-ish thing (where you marshal an expression over to the other process and then convert the expression into code on the other side), your aren't going to get what you describe. The typical way to do this is have Process B expose an RPC-ish API (WCF, REST, DCOM, whatever) and have process A call into that API (which it can do asynchronously).
– Flydog57
Aug 10 at 23:43





Actually both processes have the same codebase, so theoretically all we have to do is serialize/deserialize the data and state machine and make another call to state machine to resume execution on another processes.
– Rauf
Aug 11 at 7:13





No, this isn't how async/await are designed. What you're describing sounds more like it needs a proper message bus or something like that doing the communication side and farming out responses to listeners.
– Damien_The_Unbeliever
Aug 11 at 7:15


async


await





And it's not really the continuation that's the problem - it's where you get a Task from that represents the ongoing work that await is going to wait for completion. If you have a method returning a Task, there's no way to copy/pass that Task to another process. Sure, you can do some kind of proxying between processes but the processes have to know about this proxying mechanism and by specifically written to work with it.
– Damien_The_Unbeliever
Aug 11 at 7:21



Task


await


Task


Task





Interprocess communication is provided by system APIs. For example on windows you have these: docs.microsoft.com/en-us/windows/desktop/ipc/… but .NET doesn't provide it. async/await abstracts over threads, which can't simply be sent to another process. You can only send data. If you want it to be platform independent and/or between multiple machines you need to use network.
– Chris Rollins
Aug 11 at 7:35





2 Answers
2



Yes, it's possible but you'll have to solve couple of major problems apart of workload distribution problems (like load balancing, failure tolerance, etc.). First you'll need to customize the async/await state machine generation possibly with Roslyn in the way similar the Roslyn does it but with necessary modifications and build-in this custom code generation into general build pipeline. Second problem related directly to the changes you'll need to introduce in the "distributed" state machine. In particular there should be serialization/deserialization mechanism which would be able to get the entire state of the state machine instance (including custom variables) and send it on wire or get it from there to restore the state (the state should be synchronized for all instances of a state machine so that continuations can work with the same values of local variables). Obviously the serialization and deserialization should be part of code generation as it will have to deal with local variables. Here is the place where some pitfalls can be encountered since serialization typically has some limitations like non-public members serialization, etc and you will unlikely want to limit usage of local variables inside the async methods by serializable types only. And at last you'll need to generate the distributed communication logic inside the state machine (possibly in the MoveNext method). But again there are pitfalls: as communication mainly implies I/O operations you'll likely want to use native async/await mechanism for efficiency which means that the distributed async/await should be distinguished somehow from the native one during the code generation.


MoveNext



Summing this up I'd say that it's possible to implement (with significant effort) but not very practical as async/await was designed with focus on I/O bound operations where it is the most efficient. However distributed I/O load (unlike distributed CPU load) is rather exotic thing due to the nature of I/O operations which scalability mainly rely on the communication channels bandwidth (network, devices) and not so dependent on number of computational units (nodes, CPUs, cores, etc).



For this question:
"is it possible to break somehow the method to the state machine like async/await does so that the continuation can be resumed on a different process and even on a different server?""



You may want to use Threading.Mutex. You can name a Mutex so you can share this Mutex with other processes. Task will not work for this scenario but the effect is similar.
So,
App Instance1 Thread 1-> MethodA (Acquire the mutex) do the part that matters matters and release the Mutex
App Instance1 Thread 2 -> MethodB Is Waiting for Mutex to be released and if it is the first to get the release, it will acquire the Mutex and continue what it needs to do
App Instance2 Thread -> MethodB Is Waiting for Mutex to be released and if it is the first to get the release, it will acquire the Mutex and continue what it needs to do



For inter machines, things get complicated.





That's not exactly the issue. The issue is that the code should remain exactly as it is shown. To make it happen we need to make it so continuation may resume on another process/machine.
– Rauf
Aug 10 at 21:55






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard