Search code examples
noflo

How do I use groups in NoFlo?


NoFlo Components documentation mentions groups but doesn't explain what they are used for and how they should be used.

Could somebody explain what role groups play in NoFlo, how groups and nested groups should be used and how it affects Asynchronous components?


Solution

  • The concept of groups is described as "bracket IPs" in the FBP book.

    Basically begingroup and endgroup are special packet types that specify that data packets sent between them contain that group as metadata.

    Think of it a bit like XML:

    <somegroup>
      <innergroup>
        data
      </innergroup>
    </somegroup>
    

    In NoFlo this would work with:

    @outPorts.out.beginGroup 'somegroup'
    @outPorts.out.beginGroup 'innergroup'
    @outPorts.out.send "data"
    @outPorts.out.endGroup()
    @outPorts.out.endGroup()
    

    The receiving inport gets these via the begingroup and endgroup events and can either do something with them or ignore them. Usually a good behavior with components that don't utilize groups but perform some transformations on information packets is to at least pass them onwards.

    @inPorts.in.on 'begingroup', (group) =>
      @outPorts.out.beginGroup group
    @inPorts.in.on 'data', (data) =>
      # do something and then send
    @inPorts.in.on 'endgroup', =>
      @outPorts.out.endGroup()
    

    So, groups can be seen as a way to supply some "metadata" for your packets. For example, NoFlo's when filesystem/ReadFile sends the contents of a file out as a packet, it surrounds it with a group named with the file's path.

    Groups can also be super-useful for merging asynchronous flows. For example, webserver/Server generates a unique group identifier for every request it gets. If you do database queries or other async operations before responding to a request, you can use these groups for merging the results back before writing a response.