Question

I'm currently looking into ways to simulate the transmission of resources and messages between connected objects such as power to devices or control messages over a networked system:

enter image description here CLICK FOR LARGER IMAGE.

I've been recently looking into TPL Dataflow not for its threading and parallelism but for how well it can implement pipelining of data without large messy code handling edge cases. The simulation will only run maybe once every 500ms or so and is really not time critical.

I've been playing around with the library and have read the documentation and few times now but I'm struggling to realize a solution with it. Of the node concepts above pictured I'm not sure what would fit the Dataflow nodes.

I would love to get some advise around whether TPL Dataflow is a good fit here, and if so a basic implementation of each of the pictured nodes in the Dataflow Block counterparts.

Was it helpful?

Solution 2

After much thought, prototyping and research I've finally implemented the solution using Events and Delegates and its working quite well!

The only major design problem is that there will be cases where messages will enter an infinite loop if, for example, 3 distribution nodes were connected in a triangle. Or if a node is connected to itself or 2 nodes connected to each other more than once. I covered each of these edge cases with some simple logic in the event listener connections:

public bool ConnectTo(Node peerNode)
        {
            EthernetPort peerPort   = peerNode.GetFreePort();
            EthernetPort myPort     = this.GetFreePort();

            // Perform a check for free ports for both peers:
            if (peerPort == null || myPort == null)
                return false; // Either myself or my peer do not have a spare port.

            // Perform a check to make sure these nodes aren't already connected:
            if (this.HasConnectedNode(peerNode))
                return false;

            // Connect the two ports:
            myPort.Connect(peerNode, peerPort);
            peerPort.Connect(this, myPort);
            return true;
        }
public bool HasConnectedNode(Node node) {
            foreach (var port in ethernetSwitch.ethernetPorts)
            {
                if (port.peerNode == node)
                    return true; // Found a port already connected to this node.
            }

            return false; // No port has this node connected to it.
        }

Finally, just in case I missed something or to simply feel safe about it, I implemented a custom EventArgs type with a int timeToLive variable. This variable is decremented each time a node handles the message and if it hits 0 then the message is discarded.

OTHER TIPS

I don't think TPL Dataflow fits this well. There are several reasons:

  1. TDF doesn't have duplex (two-way) communication, you would somehow need to bolt that on.
  2. In TDF, blocks usually receive messages and then produce more messages to send along the pipeline. That doesn't seem to be what you need (with the exception of your hub node), at least not logically.

But I think your requirements don't require something as heavy-weight as TDF. I think what you should do is:

  1. Create a simple library for message sending, possibly using a client-server-like architecture: a client (e.g. consumer node or distribution node) sends a message to a server (e.g. distribution node or power node) and the server replies, possibly with some delay. If a client is connected to multiple servers, it sends the same message to all of them and decides how to handle multiple responses (probably by accepting only the first one; this also means client has to be able to reject a response).
  2. Create a PowerStore class that stores power and can be used to take it. It will return a Task, so the consumer can wait until the power is available.
  3. Using the above two points, it should be relatively simple to build your nodes.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top