Skip to content


Compile subgraphs into parent graphs before executing #42

merged 2 commits into from

3 participants

NoFlo member

My other two outstanding pull requests (#40, #41) deal with subgraphs. They have always felt like unsafe patches to me, but I think I finally got a cleaner solution to it, but it does change the API so I really look forward to some input.

I figured that the problems that I've been encountering is due to the fact that subgraphs are initialized after the parent graph is set up and ready to send IPs. This solution involves pre-compiling the sub-graphs directly into the parent graph (and do so recursively) before executing the graph.

So, in this completely trivial example:

# abc.fbp
'group' -> GROUP Group(Group)
Merge(Merge) OUT -> IN Group() OUT -> IN Split(Split)
# def.fbp
'abc.fbp' -> GRAPH A(Graph)
Merge(Merge) OUT -> IN A.Merge()
# main.fbp
'def.fbp' -> GRAPH A(Graph)
'initial' -> IN Merge(Merge) OUT -> IN A.Merge()
A.A.Split() OUT -> IN Output(Output)

This would yield (invisible to the programmer):

'group' -> GROUP A.A.Group(Group)
A.A.Merge(Merge) OUT -> IN A.A.Group() OUT -> IN A.A.Split(Split)

A.Merge(Merge) OUT -> IN A.A.Merge()

'initial' -> IN Merge(Merge) OUT -> IN A.Merge()
A.A.Split() OUT -> IN Output(Output)

What this does is eliminate all the testing and waiting for a ready-state. The namespace should also avoid any name clash since FBP doesn't have dots in component names.

The downside of this approach is the change at the API level.

Would this be a long-term solution to the problem?


This pull request passes (merged 12c1ec3 into 5f4fcfa).


This pull request passes (merged 707a274 into 5f4fcfa).

NoFlo member

I have been reading Morrison's book and realized that the concept of a graph is to look like a regular component. Having the dot-notation breaks the black-box-ness of FBP.

So I guess we should always stick with the PROCESS.PORT convention, but I'd still be for the idea of compiling the graphs before execution.


This pull request passes (merged 8cbfff2 into 5f4fcfa).

@bergie bergie merged commit 7f015cf into noflo:master

1 check passed

Details default The Travis build passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 27, 2012
  1. @kenhkan
Commits on Sep 3, 2012
  1. @kenhkan
Showing with 33 additions and 1 deletion.
  1. +33 −1 src/lib/
34 src/lib/
@@ -1,9 +1,13 @@
+fs = require 'fs'
class Fbp
matchPort: new RegExp "([A-Z\.]+)"
- matchComponent: new RegExp "([A-Za-z]+)\\(([A-Za-z0-9\/\.]+|)\\)"
+ matchComponent: new RegExp "([A-Za-z\.]+)\\(([A-Za-z0-9\/\.]+|)\\)"
+ matchComponentGlobal: new RegExp "([A-Za-z\.]+)\\(([A-Za-z0-9\/\.]+|)\\)", "g"
matchInitial: new RegExp "\'(.+)\'"
matchConnection: new RegExp "\-\>"
matchSeparator: new RegExp "[\\s,\\n]"
+ matchSubgraph: new RegExp "\n *\\'(.+)\\' *-> *GRAPH *([A-Za-z\\.]+)\\(Graph\\)"
constructor: ->
@lastElement = null
@@ -14,8 +18,36 @@ class Fbp
@nodes = {}
@edges = []
+ loadFile: (file) ->
+ fs.readFileSync file, "utf-8", (err) ->
+ throw err if err
+ # Compile subgraphs INTO the parent graph
+ compileSubgraphs: (string) ->
+ loop
+ match = string.match(@matchSubgraph)
+ # Done when there's no more subgraphs
+ unless match?
+ return string
+ else
+ [match, file, name, index, original] = match
+ # Get the FBP of the subgraph and compile that first
+ fbp = @compileSubgraphs(@loadFile(file))
+ # Affix the name to the beginning of all components in the subgraph
+ fbp = fbp.replace(@matchComponentGlobal, "#{name}.$1($2)")
+ # Replace the graph statement with the FBP
+ string = string.replace(match, "\n#{fbp}")
parse: (string) ->
currentString = ""
+ string = @compileSubgraphs("\n#{string}") # Pad string with newline in case the first line is a graph include
for char, index in string
@currentLine++ if char is "\n"
Something went wrong with that request. Please try again.