views:

93

answers:

2

Hi,
I'm writing some kind of Computing farm with central server giving tasks and nodes that compute them.

I wanted to write it in such way, that nodes don't know what exactly they are computing. They get (from server) an object that implements IComputable iterface, has one method, .compute() that returns IResult type object and send it to the server.

Server is responsible for preparing these object and serving them through .getWork() method on wcf service, and gets the results with .submitResult(IResult result) method.

Problem is, that worker nodes need to know not only the interface, but full object implementation. I know that Java can serialize method (probably to bytecode) through RMI. Is it possible with c# ?

+1  A: 

What you will have to do is put the type which implements the method you are describing into a separate assembly. You can then send the assembly as a byte array to your server, where it will load the assembly, insptect it for types that fit your interface, and then load them. This is the basic pattern for plug-ins using .Net.

Some care has to be taken though. If you are accepting code from arbitrary sources, you will have to lockdown what these loaded assemblies can do (and it is good practice to do even if you trust the source).

A good classic example for how to do this is the Terrarium project. It is a case study that Microsoft produced that involved the viral spreading of arbitrary assemblies in a secure fashion.

Chris
Passing DLLs with arbitrary code is probably a viable solution, but ensuring security of that can be crazy :D
A: 

You can do

System.Expression.LambdaExpression<Func<result>> lambda = MyFunction;

and then you can serialize expression to string and deserialize on the server

This will only work for a limited subset of values for "MyFunction". For example, it cannot use any captured variables. These will not be translatable to text and back because they exist in memory on the source machine.
Chris
About limited subset - true. Captured variables can be evaluated to their values and posted as Constants, so var i = 1; ExecuteOnServer(Compute(i)) becomes in serialized form "(Call Compute 1)". Also I assumed some sort of Command pattern rather than decompiling all functions and posting IL.