Search code examples
c#ignite

How distributed closures are sent across ignite nodes


I am looking at the example from the Apache Ignite documentation about the use of distributed closures.

https://apacheignite-net.readme.io/docs/distributed-closures

Based on my understanding it is possible to define the closure in the client node by implementing the IComputeFunc interface. What is not completely clear to me is how the implementation of the interface is being delivered to the server nodes in the cluster. Is there any documentation of this mechanism? Are there any limitations about the code that the implementation of the closure may contain? E.g. is it allowed to make http requests? Call code from external nuget packages?

I've tried looking at the source code of the project. It seems that the implementation of IComputFunc is being somehow binary serialized using the BinaryWriter.writeobjectdetached method. I didn't manage to get further than that in my investigation.

Below is the example that I was looking at:

async void Compute()
{
    using (var ignite = Ignition.Start())
    {
        var funcs = "Count characters using compute func".Split(' ')
          .Select(word => new ComputeFunc { Word = word });

        ICollection<int> res = ignite.GetCompute().Call(funcs);

        // Async mode
        res = await ignite.GetCompute().CallAsync(funcs);

        var sum = res.Sum();

        Console.WriteLine(">>> Total number of characters in the phrase is '{0}'.", sum);
    }
}

[Serializable]
class ComputeFunc : IComputeFunc<int>
{
    public string Word { get; set; }

    public int Invoke()
    {
        return Word.Length;
    }
} 

Solution

  • If this class is present on remote node, it gets used as is, after deserialization. If this class is absent on remote node, then Peer Assembly Loading will kick in if enabled, it will send required assemblies to remote node.

    Since CIL code is pretty well-defined it is a painless process: it might as well stream most of your dependencies to remote nodes on request, including libraries, etc. There is limitation to this mechanism in that it will not Peer Load caches' Key-Value classes. So if you need to operate on those, you need to distribute it between all nodes.

    This code will work with same permissions as your generic Ignite code, so yes, there's no reason why it won't make HTTP calls. Note that it might still be better to explicitly add most libraries to all nodes and only Peer Load code that changes often.