-
May 12 2015, Verona
Massimiliano Mantione
Passionate about languages and compilers
Worked in the V8 team in Google
Overall, worked on JIT compilers for +7 years
Now working on scalable, fault tolerant,
web facing distributed systems...
...serving vitual reality on the web!
I started as a Javascript hater
When I sow Javascript for the 1st time (in 1995) I vowed that I would never touch such an abomination, even with a 10 feet pole
Eventually, I changed my mind, but...
Let's change subject!
Why?
I tried several, and
I was not happy...
Simple is good
Everybody starts with a few scripts
The project grows, the scripts get slow...
Dependency tracking is the needed feature
(performing build steps in parallel also helps)
independency
(A, B, C, need A, skip B and C)
dependency
(A ► B ► C, need C, skip A and B)
parallelism
(A, B, C, need all, run in parallel)
just a task runner
very verbose
build files get huge quickly
A bit more pleasant
Streams are interesting
If you have multi-file operations you end up fighting it badly
Why do I have to write code in a specific language?
Brilliant concept
So-and-so execution
sometimes all those temporary trees get in your way
Why do I have to write code in a specific language?
Webpack (specific use, fast only when hot)
Jake (mostly like make)
Gradle (you must know Groovy)
Blaze (more about this later)
Why do I have to write code in a specific language?
deterministic
reliable
fast
Builds happen in a build environment
The environment is a file tree
Each build step mutates the file tree
How do you reliably detect if the build environment contains the proper result of a build step?
You don't...
You use the file system and check the mtime of input and output files
(Jake, Make...)
(can get cumbersome)
The build system has an internal graph that carries the build artifacts
(Gulp, WebPack...)
Fast when the build system stays running
(like while watching)
Track contents and not mtime!
Just like Git does
...and just like Bazel does...
Store everything in a content addressable file system
(Git is a content addressable database)
Use this file system as environment for build steps
Isolate each build step in a container
Expose the inputs as a read only tree
Capture the output and snapshot it in the content addressable storage
Cache every computation!
Fast
Correct
Pick two!
(just like Bazel)
meet
-
Immutable, copy on write data structures
(with structural sharing)
Memoization of function results
Both, but each where appropriate
The build graph is declarative and functional
Each build step is imperative but confined inside its container
Programming language independence!
-
meet
-
A CI system is a build system...
...with its own configuration language!
The dependency graph description is usually too verbose to be practical
Tipically only one or two developers in a team know how to work on it
Nobody wants to learn one more build system
FFTT performs builds
Something else detects changes in the source and invokes builds
This "something else" might watch a remote git repository...
...builds could trigger deployments...
Add a web view of the content addressable store...
Why docker builds are slow
Use the FFTT repo as a read only volume
Deploy containers mounting that volume
(let them access that volume over NFS or a clustering file system like GlusterFS)
No need to wait for a rebuild, ever!
A side effect of the pure functional nature of FFTT
Actually, the simplest way to implement it is naturally parallel!
Using docker swarm (or maybe kubernetes) as container runner the builds would be distributed
The repo, and the linking issue
The exposed file system and fuse
The repo, as it could be
How Javascript has been used
Atomic operations on the repo
Garbage collection
Fuse view of the repo
Explicit tagging
Repo transfer network protocol
Repo web browser
Take Over the World!
Even if you will not use FFTT, I hope you learned something about build tools
Maybe you'll all switch to Bazel...
If you did like it, please plan to contribute!
code, docs and slides are on github
twitter: @M_a_s_s_i, #metascript