Reusable Reproducible Composable Software

Overview
Fractalide

Reusable Reproducible Composable Software

LICENSE Build Status

Welcome

What is this?

Fractalide is a free and open source service programming platform using dataflow graphs. Graph nodes represent computations, while graph edges represent typed data (may also describe tensors) communicated between them. This flexible architecture can be applied to many different computation problems, initially the focus will be Microservices to be expanded out into the Internet of Things.

Fractalide is in the same vein as the NSA’s Niagrafiles (now known as Apache-NiFi) or Google’s TensorFlow but stripped of all Java, Python and GUI bloat. Fractalide faces big corporate players like Ab Initio, a company that charges a lot of money for dataflow solutions.

Truly reusable and reproducible efficient nodes is what differentiates Fractalide from the others. It’s this feature that allows open communities to mix and match nodes quickly and easily.

Features

Fractalide stands on the shoulders of giants by combining the strengths of each language into one programming model.

Op Technology Safe Zero-cost Abstractions Reuse Reproducible Distributed Type System Concurrent Service Config Man.

NixOS

+

Nix Expr

+

Rust

+

Flow-based Programming

+

Cap’n Proto

=

Fractalide Model

What’s new from different perspectives

Nix Programmers

Fractalide brings safe, fast, reusable, black-box dataflow functions and a means to compose them.

Tagline: "Nixpkgs is not enough! Here, have 'Nixfuncs' too!"

Rust Programmers

Fractalide brings reproducible, reusable, black-box dataflow functions, a means to compose them and a congruent model of configuration management.

Tagline: Safety extended beyond the application boundary into infrastructure.

Flow-based Programmers

Fractalide brings safe fast reproducible classical Flow-based programming components, and a congruent model of configuration management.

Tagline: Reproducible components!

Programmers

Fractalide brings safe, fast, reusable, reproducible, black-box dataflow functions, a means to compose them and a congruent model of configuration management.

Tagline: Here, have a beer!

Solved problems

Modules-code coupling

Language level modules become tightly coupled with the rest of the code, moving around these modules also poses a problem.

Solution

An unanticipated outcome occurred when combining FBP and Nix. It’s become our peanut butter and jam combination, so to say, but requires a bit of explaining, so hang tight.

Reproducibility

Nix is a content addressable store, so is git, so is docker, except that docker’s SHA resolution is at container level and git’s SHA resolution is at changeset level. Nix on the other hand has a SHA resolution at package level, and it’s known as a derivation. If you’re trying to create reproducible systems this is the correct resolution. Too big and you’re copying around large container sized images with multiple versions occupying gigabytes of space, too small and you run into problems of git not being able to scale to support thousands of binaries that build an operating system. Therefore Nix subsumes Docker.

Indeed it’s these simple derivations that allow python 2.7 and 3.0 to exist side-by-side without conflicts. It’s what allows the Nix community to compose an entire operating system, NixOS. These derivations are what makes NixOS a congruent configuration management system, and congruent systems are reproducible systems. They have to be.

Reusability

Flow-based programming in our books has delivered on its promise. In our system FBP components are known as a nodes and they are reusable, clean and composable. It’s a very nice way to program computers. Though, we’ve found, the larger the network of nodes, the more overhead required to build, manage, version, package, connect, test and distribute all these moving pieces. This really doesn’t weigh well against FBP’s advantages. Still, there is this beautiful reusable side that is highly advantageous! If only we could take the good parts?

Reproducibility + Reusability

When nix is assigned the responsibility of declaratively building fbp nodes, a magic thing happens. All that manual overhead of having to build, manage and package etc gets done once and only once by the node author, and completely disappears for everyone thereafter. We’re left with the reusable good parts that FBP has to offer. Indeed the greatest overhead a node user has, is typing the node's name. We’ve gone further and distilled the overhead to a few lines, no more intimidating than a typical config file such as Cargo.toml:

{ agent, edges, mods, pkgs }:

agent {
  src = ./.;
  edges = with edges; [ PrimText FsPath ];
  mods = with mods.rs; [ rustfbp rusqlite ];
  osdeps = with pkgs; [ sqlite pkgconfig ];
}

Now just to be absolutely clear of the implications; it’s possible to call an extremely complex community developed hierarchy of potentially 1000+ nodes, where each node might have different https://crates.io dependencies, they might have OS level dependencies such as openssl etc and nix will ensure the entire hierarchy is correctly built and made available. All this is done by just typing the node name and issuing a build command.

It’s this feature that sets us apart from Google TensorFlow and Apache-NiFi. It contains the DNA to build a massive sprawling community of open source programmers, this and the C4, that is. It’s our hope anyway!

Complex configuration management model

The vast majority of system configuration management solutions use either the divergent or convergent model.

We’re going to quote Steve Traugott’s excellent work vebatim.

Divergent

divergent

"One quick way to tell if a shop is divergent is to ask how changes are made on production hosts, how those same changes are incorporated into the baseline build for new or replacement hosts, and how they are made on hosts that were down at the time the change was first deployed. If you get different answers, then the shop is likely divergent.

The symptoms of divergence include unpredictable host behavior, unscheduled downtime, unexpected package and patch installation failure, unclosed security vulnerabilities, significant time spent "firefighting", and high troubleshooting and maintenance costs."

— Steve Traugott

Convergent

convergent

"The baseline description in a converging infrastructure is characteristically an incomplete description of machine state. You can quickly detect convergence in a shop by asking how many files are currently under management control. If an approximate answer is readily available and is on the order of a few hundred files or less, then the shop is likely converging legacy machines on a file-by-file basis.

A convergence tool is an excellent means of bringing some semblance of order to a chaotic infrastructure. Convergent tools typically work by sampling a small subset of the disk - via a checksum of one or more files, for example - and taking some action in response to what they find. The samples and actions are often defined in a declarative or descriptive language that is optimized for this use. This emulates and preempts the firefighting behavior of a reactive human systems administrator - "see a problem, fix it." Automating this process provides great economies of scale and speed over doing the same thing manually.

Because convergence typically includes an intentional process of managing a specific subset of files, there will always be unmanaged files on each host. Whether current differences between unmanaged files will have an impact on future changes is undecidable, because at any point in time we do not know the entire set of future changes, or what files they will depend on.

It appears that a central problem with convergent administration of an initially divergent infrastructure is that there is no documentation or knowledge as to when convergence is complete. One must treat the whole infrastructure as if the convergence is incomplete, whether it is or not. So without more information, an attempt to converge formerly divergent hosts to an ideal configuration is a never-ending process. By contrast, an infrastructure based upon first loading a known baseline configuration on all hosts, and limited to purely orthogonal and non-interacting sets of changes, implements congruence. Unfortunately, this is not the way most shops use convergent tools…​"

— Steve Traugott

Solution

Congruent
congruent

"By definition, divergence from baseline disk state in a congruent environment is symptomatic of a failure of code, administrative procedures, or security. In any of these three cases, we may not be able to assume that we know exactly which disk content was damaged. It is usually safe to handle all three cases as a security breach: correct the root cause, then rebuild.

You can detect congruence in a shop by asking how the oldest, most complex machine in the infrastructure would be rebuilt if destroyed. If years of sysadmin work can be replayed in an hour, unattended, without resorting to backups, and only user data need be restored from tape, then host management is likely congruent.

Rebuilds in a congruent infrastructure are completely unattended and generally faster than in any other; anywhere from ten minutes for a simple workstation to two hours for a node in a complex high-availability server cluster (most of that two hours is spent in blocking sleeps while meeting barrier conditions with other nodes).

Symptoms of a congruent infrastructure include rapid, predictable, "fire-and-forget" deployments and changes. Disaster recovery and production sites can be easily maintained or rebuilt on demand in a bit-for-bit identical state. Changes are not tested for the first time in production, and there are no unforeseen differences between hosts. Unscheduled production downtime is reduced to that caused by hardware and application problems; firefighting activities drop considerably. Old and new hosts are equally predictable and maintainable, and there are fewer host classes to maintain. There are no ad-hoc or manual changes. We have found that congruence makes cost of ownership much lower, and reliability much higher, than any other method."

— Steve Traugott

Fractalide does not violate the congruent model of Nix, and it’s why NixOS is a dependency. Appreciation for safety has extended beyond the application boundary into infrastructure as a whole.

Language choice

A language needed to be chosen to implement Fractalide. Now as Fractalide is primarily a Flow-based programming environment, it would be beneficial to choose a language that at least gets concurrency right.

Solution

Rust was a perfect fit. The concept of ownership is critical in Flow-based Programming. The Flow-based scheduler is typically responsible for tracking every Information Packet (IP) as it flows through the system. Fortunately Rust excels at getting the concept of ownership right. To the point of leveraging this concept that a garbage collector is not needed. Indeed, different forms of concurrency can be layered on Rust’s ownership concept. One very neat advantage Rust gives us is that we can very elegantly implement Flow-based Programming’s idea of concurrency. This makes our scheduler extremely lightweight as it doesn’t need to track IPs at all. Once an IP isn’t owned by any component, Rust makes it wink out of existance, no harm to anyone.

API contracts

It’s easy to disrespect API contracts in a distributed services setup.

Solution

We wanted to ensure there was no ambiguity about the shape of the data a node receives. Also if the shape of data changes, the error must be caught at compile time. Cap’n Proto schema fits these requirements, and fits them perfectly when nix builds the nodes calling the Cap’n Proto schema. Because, if a schema changes, nix will register the change and will rebuild everything (nodes and subgraphs) that depends on that schema, thus catching the error. We’ve also made it such, during graph load time agents cannot connect their ports unless they use the same Cap’n Proto schema. This is a very nice safety property.

The mandatory Hello-like World example.

From a fresh install of NixOS (using the nixos-unstable channel) we’ll build the fractalide virtual machine (fvm) and execute the humble NAND logic gate on it.

$ git clone https://github.com/fractalide/fractalide.git
$ cd fractalide
$ nix-build --argstr node test_nand
...
$ ./result
boolean : false

Contributing to Fractalide

Contributing FAQ

Q: I’m kind of new to Github, how do I get started?

  • Read the C4.2 (Collective Code Construction Contract) and the line by line explanation of the protocol.

  • Fork this github repository under your own github account.

  • Clone your fork locally on your development machine.

  • Choose one problem to solve. If you aren’t solving a problem that’s already in the issue tracker you should describe the problem there (and your idea of the solution) first to see if anyone else has something to say about it (maybe someone is already working on a solution, or maybe you’re doing somthing wrong). If the issue is in the issue tracker, you should comment on the issue to say you’re working on the solution so that other people don’t work on the same thing.

  • Add the Fractalide repository as an upstream source and pull any changes:

$ git remote add upstream git://github.com/fractalide/fractalide //only needs to be done once
$ git checkout master //just to make sure you're on the correct branch
$ git pull upstream master //this grabs any code that has changed, you want to be working on the latest 'version'
$ git push //update your remote fork with the changes you just pulled from upstream master
  • Create a local branch on your machine git checkout -b branch_name(it’s usually a good idea to call the branch something that describes the problem you are solving).

  • Solve the problem in the absolute most simple and fastest possible way with the smallest number of changes humanly possible. Tell other people what you’re doing by putting very clear and descriptive comments in your code every 2-3 lines. Add your name to the AUTHORS file so that you become a part owner of Fractalide.

  • Commit your changes to your own fork: Before you commit changes, you should check if you are working on the latest version (again). Go to the github website and open your fork of Fractalide, it should say This branch is even with Fractalide:master. If not, you need to pull the latest changes from the upstream Fractalide repository and replay your changes on top of the latest version:

$ git stash //save your work locally
$ git checkout master
$ git pull upstream master
$ git push
$ git checkout -b branch_name_stash
$ git stash pop //_replay_ your work on the new branch which is now fully up to date with the fractalide repository

Now you can add and commit your changes:

$ git add changed_file.js //repeat for each file you changed
$ git commit -m 'problem: very short description of problem //do not close the '', press ENTER two (2) times
>
>solution: short description of how you solved the problem.' //Now you can close the ''. Also mention the issue number if there is one (e.g. #6)
$ git push //this will send your changes to _your_ fork on Github
  • Go to your fork on Github and select the branch you just worked on. Click "pull request" to send a pull request back to the Fractalide repository.

  • Send the pull request.

Q: What happens after I send a pull request?

If your pull request contains a correct patch (read the C4) a maintainer should merge it. If you want to work on another problem in the meantime simply repeat the above steps starting at:

$ git checkout master

Q: Can I be paid to contribute to Fractalide?

Yes, this is sometimes possible. Your first step is to very carefully read and understand everything above, including the linked files, then start fixing problems and sending pull requests! If your code is amazing and brilliant but you don’t understand the contribution process we cannot consider you for a paid position. Make sure you follow the project on Github so you get updates. Contact Fractalide’s BDFL (Benevolent Dictator For Life): Stewart Mackenzie if you’ve been contributing code to Fractalide and want to keep doing it but but you require financial assistance.

Consulting and Support

Name Info Language

Stewart Mackenzie

Founder and maintainer of Fractalide

English

Denis Michiels

Founder and maintainer of Fractalide

French

License

The project license is specified in LICENSE. Fractalide is free software; you can redistribute it and/or modify it under the terms of the Mozilla Public License Version 2 as approved by the Free Software Foundation.

Social

Follow us on twitter

Thanks

  • Peter Van Roy

  • Pieter Hintjens

  • Joachim Schiele & Paul Seitz

  • P Meunier

Comments
  • Problem: we are not testing rust

    Problem: we are not testing rust

    The Mozilla Rust overlay is impure.

    Solution: Make the manifest download fixed-output.

    Add rust tests to release.nix and .travis.yml.

    The Linux test in .travis.yml is a bit ugly, but will go away once travisOrder is done over on racket2nix and can be brought over.

    opened by clacke 16
  • Problem: preliminary stages of a graph language compatible with nix not in place

    Problem: preliminary stages of a graph language compatible with nix not in place

    Solution: The current process of defining graphs seems succinct and powerful enough to describe our needs. Though there is one change needed to make initial preparation for nix integration (much later) complete. At least this allows us to get used to the new semantics of the language and when we finally integrate nix all the graphs will work with minimal changes.

    Actual behaviour to setup a node:

    (node "frame" "gui/frame")
    

    Expected behaviour to setup a node:

    (node "frame" "${gui.frame}")
    

    The name for a node should be the same as the nix attribute name surrounded by ${...}. The racket code receiving this string will conditionally execute depending on the the presence of a ${ in the beginning of the string.

    1. when compiling as racket only and no nix integration, the receiving code will see the string "${gui.frame}". Racket should then lookup the path to the gui/frame file. At a later stage we can push all the fractal into the ~/.racket/fractal directory. So racket will see ${gui.frame} and find the file ~/.racket/fractal/gui/frame.rkt. For the moment looking up in agents directory is sufficient.
    2. when we introduce nix at a later stage, nix will precompile the racket "graph" file and transform the names ${...} into "/nix/store/...". So if the receiving code of that string doesn't see a "${" then it knows to look up that absolute path "/nix/store/..." for the file.
    opened by sjmackenzie 15
  • Problem: hard reproducible bug introduced in nixpkgs caused generate-…

    Problem: hard reproducible bug introduced in nixpkgs caused generate-…

    …msg to fail

    Solution: the simplest solution is to change the package details of generate-msg so that it conforms with cargo regulations. i.e. use an underscore in the package name.

    Now Travis-ci, macos, ubuntu and nixos should all see the same build product -> generate_msg and not generate-msg on some machines.

    opened by sjmackenzie 15
  • Problem: modules/rs/crates/update.sh: Latest carnix does not work

    Problem: modules/rs/crates/update.sh: Latest carnix does not work

    Steps to reproduce:

    1. Fix that update.sh calls carnix nix. It's now called carnix generate-nix.
    2. The generated Cargo.nix requires some new parameters. Forward those from buffet.pkgs.
    3. (cd modules/rs/crates && ./update.sh)
    4. ./release.sh
    error: while evaluating the attribute 'mods.rs.cardano_0_1_0' at /home/clacke/git/fractalide/fractalide/modules/default.nix:4:3:
    attribute 'cardano_0_1_0' missing, at /home/clacke/git/fractalide/fractalide/release.nix:8:15
    
    opened by clacke 14
  • Problem: build system for Racket not present

    Problem: build system for Racket not present

    Potential solution:

    • Implement a racket2nix program that reads an info.rkt file and outputs a deps.nix file. The generation of the deps.nix file extracts information from https://github.com/racket/release-catalog/blob/master/release-catalog/pkgs-all.
    • Once racket2nix is implemented it needs to be wired into Fractalide such that one can describe Fractalide modules using this syntax: https://github.com/fractalide/fractalide/blob/master/nodes/rs/web/server/default.nix#L6 where the attribute names map directly to package names on https://pkgs.racket-lang.org/
    • Note there will be one info.rkt per fractal and not an info.rkt per module. The info.rkt will be located in the conventional $fractal/modules/rkt/ directory. The deps.nix will be generated into the same directory.
    • This solution should not only be plugged into Fractalide but also work with Fractals.
    type: for-contract 
    opened by sjmackenzie 13
  • Problem: fvm: No obvious way to send IIPs to loaded graph

    Problem: fvm: No obvious way to send IIPs to loaded graph

    The current test graph is triggered by someone clicking in the UI, but I couldn't find a way for a headless automated test to send messages to nodes inside the graph, or to the virtual input of the graph. When looking at the scheduler-agents of the application scheduler, it's the empty list.

    For automated testing, I currently set up the scheduler explicitly, rather than loading a graph via fvm.

    opened by clacke 12
  • Problem: default.nix was too complicated

    Problem: default.nix was too complicated

    WIP: Do not merge yet!

    Solution: simplify it.

    This change slightly how default.nix is working and require an update in the documentation and need a review to be sure the changes are not removing any functionality.

    Before this PR:

    $ nix-build --argstr rs test_nand
    

    After this PR:

    $ nix-build --argstr node test_nand
    

    The backend default is rust, to change it to something else, eg purs:

    $ nix-build --argstr node test_nand  --argstr backend purs
    

    cc @sjmackenzie

    opened by ericsagnes 11
  • Problem: Unable to get hyperflow to load a graph

    Problem: Unable to get hyperflow to load a graph

    How are you guys doing it?

    1. $ nix-shell -p $(nix-build -A pkgs.fractalide.env) --run hyperflow
    2. Window opens up
    3. Click Graph->Open, open e.g. test/main.
    4. Receive this:
    [ GTK nonsense filtered ]
    Agent main-graph-in-agent fails with : 
    #(struct:exn:fail:contract cadr: contract violation
      expected: (cons/c any/c pair?)
      given: '("/home/clacke/git/fractalide/no-more-fun/modules/rkt/rkt-fbp/agents/test/main.rkt") #<continuation-mark-set>)
    
    opened by clacke 10
  • Problem: define-agent: We always want to define the 'agt symbol

    Problem: define-agent: We always want to define the 'agt symbol

    We are repeating ourselves with (define agt (define-agent, as the agent loader is always looking for the agt symbol.

    Solution: define-agent or some other form includes the (define agt bit.

    opened by clacke 10
  • Problem: Hydra doesn't like `git-export` in restricted mode

    Problem: Hydra doesn't like `git-export` in restricted mode

    Hydra throws this error

    error: access to path '/nix/store/5558737hlvr00y0qf9hjjhfardn1jq8v-racket-package.nix-src/z43snhhvlbzql1id14l8s585n3i7jj05-git-export' is forbidden in restricted mode
    

    https://hydra.fractalide.com/jobset/fractalide/fractalide#tabs-errors

    opened by sjmackenzie 10
  • Problem: no

    Problem: no "hello world" for a headless fbp scheduler present

    Solution: flonly (flow only) will give the user the ablity to execute a non-gui graph in headless mode (without hyperflow)

    flonly will also be included into hyperflow to execute gui graphs. This'll be done by passing the gtk+ run canvas object into the flonly fbp scheduler, thus providing gui nodes something to draw on.

    Essentially Hyperflow will dynamically reconfigure flonly on the fly by calling flonly APIs to hotswap and connect/disconnect nodes that have been compiled by Hyperflow (via nix). Hyperflow will provide the full nix/store/ path to the node in question.

    The short and unique name "flonly" was chosen as it'll be executed from the command line. Programmers like short memorable unique names that won't collide with other cli names in their environment. "scheduler" would be a bad name as it's too generic. flonly is also a play on the word "lonely", as one would be rather lonely without a head. Lastly if one squints one's eyes and skips a few letters one'll see the word "fly", which hints at flonly's on the fly graph reconfiguring ability.

    opened by sjmackenzie 9
  • Attempt to use

    Attempt to use

    Running through initial setup on both NixOS/Ubuntu:

    ...
    copying path '/nix/store/7yh730wmnkllvr30h3vdq0zq1yjqrsd3-openssl-1.0.2p-bin' from 'https://cache.nixos.org'...
    copying path '/nix/store/w70ksa7qjl493p30gnwl03jkambn2gcn-openssl-1.0.2p-dev' from 'https://cache.nixos.org'...
    copying path '/nix/store/gzvgpbqlmmxqn6sbfm2lx1przyfh2wc4-curl-7.62.0-dev' from 'https://cache.nixos.org'...
    building '/nix/store/baw9hb03szphw5csf29d736bwdyhs878-source.drv'...
    
    trying https://github.com/mozilla/nixpkgs-mozilla/archive/7e54fb37cd177e6d83e4e2b7d3e3b03bd6de0e0f.tar.gz
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   165    0   165    0     0   1309      0 --:--:-- --:--:-- --:--:--  1320
    100 53996    0 53996    0     0   175k      0 --:--:-- --:--:-- --:--:--  175k
    unpacking source archive /build/7e54fb37cd177e6d83e4e2b7d3e3b03bd6de0e0f.tar.gz
    error: attribute 'rustfbp_0_3_34_' missing, at /root/fractalide/modules/rs/crates/default.nix:7:71
    (use '--show-trace' to show detailed location information)
    
    opened by tomberek 5
  • Problem: cardano-cli is not nixified

    Problem: cardano-cli is not nixified

    This issue depends on:

    • https://nest.pijul.com/pmeunier/carnix/discussions/8
      • We can work around this.
    • https://nest.pijul.com/pmeunier/carnix/discussions/18
      • Might just be an education issue about carnix's expected behavior.

    Preliminary, non-working branch in https://github.com/clacke/cardano-cli/tree/nixify . To get a nixified source tree, run ./nix/nixify.sh .

    opened by clacke 1
  • [racket-fbp][Edge]

    [racket-fbp][Edge]

    For the moment, there is no way to use an edge in another edge.

    Solution

    Provide a require/edge method in the edge definition. It is not the same as the agent one.

    (require fractalide/modules/rkt/rkt-fbp/edge)
    (require/edge ${....})
    
    (provide ...)
    
    opened by dmichiels 0
  •  [RustFBP][Edge] can't find crate for ...

    [RustFBP][Edge] can't find crate for ...

    Steps to reproduce

    The idea here is to use a crate in an edge, like cardano_storage. In a edge file, trying to do :

    use cardano_storage::{Storage};
    

    lead to

    unresolved import `cardano_storage`
    

    and if we add

    extern crate cardano_storage;
    

    we get

     can't find crate for `cardano_storage`
    

    expected behaviour

    the code compiles cleanly
    

    Solutions?

    RustFBP level

    The problem is that for the moment, the edges are all in the "rustfbp" compilation. So if we want to add crate in an edge, we will need to compile RustFBP with the external crate. This solution also means we will need to compile RustFBP with all the nodes we will use, no way to add a new node while a program is running. Not very dynamic.

    The node level

    In the past, we used to put all the content of the edge's files on the top of the agent, so that each agent will have to import the external crate needed by the edges. It can lead to some "boiler-plate" and "strange" dependency management.

    The edge level

    Perhaps it is possible to consider each edge as an entire crate? its will manage its own dependencies. The agent will do :

    extern crate cardano_blockchain;
    use cardano_blockchain::*;
    
    agent!{
        input( in: CardanoBlockchain)
    ....
    

    This seems the cleaner solution, even more that we can clean the "boilerplate" import with a macro like the racketone :

    edge!(cardano_blockchain);
    

    But it also mean we will have more library to manage (one more for each edge), and also the compilation of the different external crates of each edge (which can be manage with nix, xin, cargo workspace, ...).

    The problem with the node level and edge level

    We put all the edge declaration at the rustFBP level in this commit, because we had problem with multiple compilation of the RustFBP crate shared by the agent, when connected them together. It is possible to have another solution, that use "raw pointer", because we now the nodes can be connected (it is the same struct, compiled with the same version of everything). I have a POC of that.

    opened by dmichiels 1
  • Problem: Name conflicts between subgraph nodes and parent graph nodes

    Problem: Name conflicts between subgraph nodes and parent graph nodes

    If I have a subgraph named "foo" that has a node "bar", and I want to name a node "foo-bar", the names will conflict and I will get nasty surprises.

    This may sound far-fetched, and the obvious workaround is "don't do that", but nodes are supposed to be able to be used as black boxes, and I may not have written the subgraph myself.

    I ran into this tonight, when I extracted a bunch of nodes into subgraph. One node was in, a filter for incoming messages to the main node in subgraph. Coincidentally I also wanted to filter incoming messages to the parent graph, which would be forwarded to subgraph, so the obvious name for that node was subgraph-in, and so subgraph-in ended up sending messages to itself.

    Solution: Generate unique names for subgraph nodes as they are loaded and renamed -- keep track of these names so that internal and virtual edges do not miss their mark.

    Probably use (gensym).

    This is an issue that may result in cascading changes through the code base, so take care.

    Also, consider whether the user will find error message mentioning 43__foo-57__bar useful. Maybe it's worth keeping both machine names and human-readable names around.

    Alternative solution: Just use a weirder separator than -.

    opened by clacke 2
  • Problem: hyperflow creating subprocesses

    Problem: hyperflow creating subprocesses

    documenting this note so we don't forget to check this out.

    Chromium spins of opengl subprocesses to handle tabs. Racket supports opengl bindings so we should explore if it's possible. But in reality racket probably has sufficient concurrency features to do this. Just how do we keep the graphics together giving it a one-app feel.

    opened by sjmackenzie 0
Owner
Fractalide
Cheapest data dissemination ever
Fractalide
Reproducible builds, dev envs and deployments.

?? Toros An implementation of Nix in Rust. Syntax support: With NixEL Interpreter support: Int Binding (aliasing) Let-in (flat bindings without interp

Kevin Amado 35 Dec 23, 2022
Authenticate a tarball through a signed tag in a git repository (with reproducible builds)

auth-tarball-from-git Authenticate a tarball through a signed tag in a git repository (with reproducible builds). The signed git tag contains a hash o

null 14 Aug 16, 2022
Dependency lockfiles for a reproducible build environment 📦🔒

repro-env Imagine you had a tool that takes a config like this: # repro-env.toml [container] image = "rust:1-alpine3.18" and turns it into something l

null 16 Jul 11, 2023
Reusable components for the Arduino Uno.

Ruduino This library provides a set of reusable components for the Arduino Uno. Overview Register and bit definitions use ruduino::cores::current::POR

The AVR-Rust project 610 Dec 28, 2022
wait-free spsc linked-list queue with individually reusable nodes

A wait-free single-producer single-consumer linked-list queue with individually reusable nodes.

glowcoil 22 Dec 26, 2022
Flexible, reusable reinforcement learning (Q learning) implementation in Rust

Rurel Rurel is a flexible, reusable reinforcement learning (Q learning) implementation in Rust. Release documentation In Cargo.toml: rurel = "0.2.0"

Milan Boers 60 Dec 29, 2022
This project attempts to allow the creation of reusable egui-themes

egui stylist Note this project is considered to be experimental and -- while used in personal projects -- may have API breaking changes without warnin

Jacobsky 22 Dec 1, 2022
An efficient method of heaplessly converting numbers into their string representations, storing the representation within a reusable byte array.

NumToA #![no_std] Compatible with Zero Heap Allocations The standard library provides a convenient method of converting numbers into strings, but thes

Michael Murphy 42 Sep 6, 2022
Fully-typed, async, reusable state management and synchronization for Dioxus 🧬

dioxus-query ?? ⚡ Fully-typed, async, reusable state management and synchronization for Dioxus ??. Inspired by TanStack Query. ⚠️ Work in progress ⚠️

Marc Espín 9 Aug 7, 2023
Structured, contextual, extensible, composable logging for Rust

Getting started Introduction FAQ Crate list slog-rs - The Logging for Rust Introduction (please read) slog is an ecosystem of reusable components for

slog-rs 1.4k Jan 3, 2023
Composable probability distributions

porco Composable probability distributions. Examples Create simple probability distributions. enum Coin { Heads, Tails, } impl Coin { fn

ming li 15 Jan 9, 2022
A super-easy, composable, web server framework for warp speeds.

warp A super-easy, composable, web server framework for warp speeds. The fundamental building block of warp is the Filter: they can be combined and co

Sean McArthur 7.5k Jan 2, 2023
🌱🦀🌱 Trillium is a composable toolkit for building web applications with async rust 🌱🦀🌱

?????? Trillium is a composable toolkit for building web applications with async rust ??????

Trillium 243 Jan 2, 2023
Wrapped ICP (WICP) - A composable and interoperable wrapped version of ICP.

Wrapped ICP - WICP Wrapped ICP (WICP) is a wrapped version of the IC's native token, ICP. Each WICP will be backed 1:1 with ICP, meaning that 1 WICP w

Psychedelic 16 Sep 23, 2022
Composable proof transcripts for public-coin arguments of knowledge

Merlin: composable proof transcripts for public-coin arguments of knowledge Merlin is a STROBE-based transcript construction for zero-knowledge proofs

dalek cryptography 99 Dec 22, 2022
Composable n-gram combinators that are ergonomic and bare-metal fast

CREATURE FEATUR(ization) A crate for polymorphic ML & NLP featurization that leverages zero-cost abstraction. It provides composable n-gram combinator

null 3 Aug 25, 2022
A collection of lower-level libraries for composable network services.

Actix Net A collection of lower-level libraries for composable network services. Example See actix-server/examples and actix-tls/examples for some bas

Actix 582 Dec 28, 2022
Composable Alternatives to Bevy's RunCriteria, States, FixedTimestep

Composable Alternatives to Bevy's RunCriteria, States, FixedTimestep This crate offers alternatives to the Run Criteria, States, and FixedTimestep sch

null 221 Jan 2, 2023
Composable WebSockets made easy, for Rust 🦀

ezsockets Have you ever struggle with creating a WebSocket server or a client in Rust? This crate is for you. High level abstraction of WebSocket, han

Grzegorz Baranski 55 Dec 30, 2022
dWallet Network, a composable modular signature network is the home of dWallets

Welcome to dWallet Network dWallet Network, a composable modular signature network is the home of dWallets. A dWallet is a noncollusive and massively

dWallet Labs 8 Feb 26, 2024