Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which of these approaches should be used to wait for input on all ports before sending packets?

Tags:

noflo

I'm still learning a lot about how FBP and NoFlo works from a process perspective, so while I can hack something together that does the job, I'm unsure whether I'm introduce problems somewhere else.

In this case, I'm creating a component that waits for an input on each of its 2 ports before sending data to the out port. Why? I need data from both inputs to construct the output packet (group name and input packet).

I've managed to achieve this using 2 approaches and I'd like to know which approach is better, or at least the up/downsides to each approach.

The component I'm talking about here is vizicities/Group:

enter image description here

Approach 1: Queuing packets from input1 internally until the input2 has received a packet

var noflo = require("noflo");

exports.getComponent = function() {
  var AddGroup = new noflo.Component();
  AddGroup.description = "This component adds a group to the data packets";

  var packets = [];
  var groupName = "";

  // Register ports and event handlers
  AddGroup.inPorts.add("in", { datatype: "all" }, function(event, payload) {
    switch (event) {
      case "begingroup":
        AddGroup.outPorts.out.beginGroup(payload);
        break;
      case "endgroup":
        AddGroup.outPorts.out.endGroup();
        break;
      case "data":
        // Queue packet
        packets.push(payload);
        break;
      case "disconnect":
        // Only send output if group has been set
        if (groupName) {
          for (var i = 0; i < packets.length; i++) {
            AddGroup.outPorts.out.beginGroup(groupName);
            AddGroup.outPorts.out.send(packets);
            AddGroup.outPorts.out.endGroup();
          }

          // Disconnect output port when input port disconnects
          AddGroup.outPorts.out.disconnect();
        }
        break;
    }
  });

  AddGroup.inPorts.add("group", { datatype: "string" }, function(event, payload) {
    switch (event) {
      case "begingroup":
        break;
      case "endgroup":
        break;
      case "data":
        groupName = payload;
        break;
      case "disconnect":
        // TODO: Does this dupe anything with the same logic on the in port?
        // Only send output if group has been set
        if (groupName) {
          for (var i = 0; i < packets.length; i++) {
            AddGroup.outPorts.out.beginGroup(groupName);
            AddGroup.outPorts.out.send(packets);
            AddGroup.outPorts.out.endGroup();
          }

          // Disconnect output port when input port disconnects
          AddGroup.outPorts.out.disconnect();
        }
        break;
    }
  });

  AddGroup.outPorts.add("out", { datatype: "all" });

  return AddGroup; // Return new instance
};

Approach 2: Using the WirePattern helper

var noflo = require("noflo");

exports.getComponent = function() {
  var AddGroup = new noflo.Component();
  AddGroup.description = "This component adds a group to the data packets";

  var config = {
    in: ["in", "group"],
    out: "out"
  };

  AddGroup.inPorts = new noflo.InPorts({
    in: {
      datatype: "string",
      required: true
    },
    group: {
      datatype: "string",
      required: true
    }
  });

  AddGroup.outPorts = new noflo.OutPorts({
    out: {
      datatype: "all"
    }
  });

  noflo.helpers.WirePattern(AddGroup, config, function(data, groups, outPort) {
    outPort.beginGroup(data.group);
    outPort.send(data.in);
    outPort.endGroup();
  });

  // Return new instance
  return AddGroup;
};

Both approaches seem to work, though clearly there must be a reason for using one over the other. Can someone clarify this for me?

like image 519
Robin Hawkes Avatar asked Jan 27 '15 11:01

Robin Hawkes


1 Answers

WirePattern is the recommended way in modern NoFlo, as it provides you with additional control on packet synchronization when needed. You can fire when all the required inputs get data, or you can require a strict group (or even packet payload) matches.

A lot of common NoFlo components are still waiting for WirePattern-ization, but for anything new, and even more so for anything asynchronous it is the recommended way.

like image 173
bergie Avatar answered Oct 14 '22 21:10

bergie