-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parallel Startup with Lazy Dependencies to speed up Agent Startup and Bootstrapping #442
Comments
IoC containers could reduce our test boilerplates when it comes to spinning up all the dependencies. I'm finding alot of boiler plate now. #446 (comment) However it's a good idea to prevent tight coupling. Right now our classes declare requirements through the constructor/asynchronous creator. The dependencies are however highly contextual.
The IoC may be to fill in some of them, but some of them, they will still require the user top pass in. What would the API look like? On the outside, when we want a object like container[CertManager] = async (c, config = {}) => {
return CertManager.createCertManager({
db: c[DB],
keyRing: c[KeyRing],
taskManager: c[TaskManager],
...config
});
};
const certMgr = await container[CertManager]() If we enable the ability to take However what about the other parameters? It would make sense that for any given function, you have to call it with parameters that are "left over".
Then further parameters could pass into the system. What about things like I wonder if a IoC container has already been developed that does this.
Remember that Unless it's defaulted to somewhere. That comes down to how the container is setup. Any parameter not passed in where required should result in an error. We could try to make TS propagate these required parameters up so it can be determined statically. |
Working on PKE has shown that IOC container had to be synchronous, it was not able to create objects asynchronously. This is because using hooks to do service location cannot be asynchronous. On the otherhand, if the IOC container was made dynamic, and dynamic registration was possible, then we could create objects asynchronously. So the issue is that we have classes that can be asynchronously created using the Actually that's not entirely true. We could do something where asynchronous classes can be instantiated, and if they are synchronously returned, then the React component can use it straight away. On the other hand, if they come as through a Is this possible? We have observables that if they don't have a default value would end up blocking on render and thus triggering a suspense component. Alternatively one could argue that the entire component would just not render until the promise is resolved. If it is possible, one could then create a universal IOC container that supports both synchronous classes and asynchronous classes. (Support both synchronous creation and destruction, and asynchronous creation and destruction). Whether it is dynamic or not is another story. Dynamic registration would not be type-safe. One could argue that dynamic registration should not be required. Anything that is likely to have dynamic registration would have to exist at a level above the object-layer. Remember that in our instantiation procedure we have:
This is due to lacking first-class modules in JS and also lacking top-level await in JS. Now that JS has top-level await, it still lacks first-class modules, but does support module monkey-patching, but that does not count as first-class modules. Anyway, introducing dynamic registration is one more layer:
Therefore the IOC container operates at the instance layer. Therefore any dynamic registration should be done as part of the instance operational state. |
I think the conclusion here is that we don't need dynamic registration. However if we investigate further how blocking react component rendering works, it'd be possible to then create a It can then work in both React contexts AND PK contexts where there's no React at all. @amydevs Thoughts? |
Specification
It appears agent startup may be slowing down our tests in the CI/CD. There are opportunities here to exploit IO parallelism during the startup procedures. What we need to is to define a
Lazy
type constructor indicating a lazy dependency.Then afterwards, for dependencies that are only needed after the domain is started, it can done like this:
The result looks like this:
You can see here that
Y
depends onX
, butY
andX
can start at the same time becauseY
only needsX
when it is finished starting. Assuming bothY
andX
are IO-bound operations, this can speed up the bootup procedure quite a bit as we now have a lazy promise graph of dependencies.Not all dependencies can do this, only that which is not required to be ready by the time the downstream dependency is starting.
This also adds additional complexity one has to understand:
start
after construction, wherestart
is for asynchronous startup and construction for synchronous startupstart
are not taken in the constructor, but lazy dependencies that are needed during creation would be set into the constructorAdditional context
Tasks
The text was updated successfully, but these errors were encountered: