fx
fx copied to clipboard
Hooks
I am thinking to add hooks mechanism to fx,
Hooks
- BEFORE_BUILD: run right before image building process.
- AFTER_BUILD: run right after image build
- BEFORE_START: run right before the service starts
- AFTER_STARTED: run right after service started
Use Case
- Dependency management
- [x] module/package that managed by dependency management tools (npm, Gem, cargo, etc)
- [ ] local source codes (require/import from relative path)
- [ ] Heath Check
Case 1: Dependency management
Normally a service is not just one single source code file, it may require different modules/packages, we normally call it dependency, and different languages provide different ways to manage dependencies, like Node uses require/import (npm), Ruby uses require (Gem), Go uses import (Go modules), etc.
When a function (to serves as an fx service) requires dependencies, for example,
const a = require('./a')
const b = require('b')
const fx = (ctx) {
a(ctx)
b(ctx)
}
a is a local package, and b is an external package. if we hope fx to support dependency, the first idea is to parse the keywords (like require, import) then install the dependency package, which means fx response for dependency parsing and dependency installation, since fx supports multiple languages, so we have to implement multiple versions of parsers and installers.
But with hook, we can move dependency management ownership to the user,
before_build: |
npm install b
cp ./a ./a
What fx needs to do is just run the script of hook at the right time.
Hooks will help a lot, I am thinking of integrating something like etcd to keep track of services and ports. With AFTER_STARTED, we can just have a simple script which will update the etcd database when a new service comes online or a port is updated.
@hongkongkiwi sounds like a good idea, would you be nice to explain it more, it'd be helpful if someone likes to add this feature.
The general idea is AFTER_STARTED will run a curl command which will hit an API endpoint.
For example curl http://127.0.0.1/services/update
We will need access to some template variables such as: service name, service port, maybe some other metadata?
Ideally this should be expressed as JSON automatically by fx when calling the hook.
We can pass these something like this e.g. curl -X post -d "$JSON" http://127.0.0.1/services/update
Then our external update point (it could be an fx function even!) will handle updating the router. We can also call directly the etcd api to update.
@hongkongkiwi
Let me clarify it a little bit. Does it look like the following workflow?
┌────────────────────────┐
│ etcd │
└────────────┬───────────┘
│ ▲
│ │
▼ │ list service
┌────────────────────────┐ ┌────────────────────┐
│ │ ─────────────────────▶│ │
│ fx service controller │ │ fx CLI │
│ │ ◀──────────────────── │ │
└────────────────────────┘ └────────────────────┘
update service
fx service controller serves a services metadata management API (like you're saying http://127.0.0.1/serivces/<service_name>/update), then fx command line will request it if somethings need to be updated.
it sounds like a workable idea, but that means we need to maintain fx service controller, current fx is a stateless command-line tool, it helps us to deploy a function to be an API without complex configure, it'd introduce a little complexity.
But I do agree and did consider introducing services management functionality into fx, appreciate that you come up with this idea, and I think another issue #460 you opened is part of this topic, it may take some time to figure it a solution for it.