-
Notifications
You must be signed in to change notification settings - Fork 21
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
Consider removing global state from the API #30
Comments
Yes, this would at least make unit testing much easier, right now complex mocks and spies are needed in many places, because of hidden dependencies on the static global deployment instance, hidden in constructors and various other places. The simplest solution I can think of is "manual dependency injection" a.k.a. just passing dependencies in constructor. It would be more "best practices" and less "tricky" Java. As for the use case, one that I had in mind is using Automation API to provide support for complex integration tests and e2e tests, that depend on infrastructure, directly from java code, using either docker and kind, or "real" infrastructure. |
Right. If we follow the way other languages do Automation API right now the script written against Automation API would get its own separate JVM, and every |
Yes. Another use case would be a build tool plugin, e.g. gradle, maven or
sbt; or a REPL usage like ammonite or scala-cli.
In both cases there is already a JVM running.
In any case, deep integrations with dev tools are interesting to me.
W dniu wt., 1.02.2022 o 20:29 Anton Tayanovskyy ***@***.***>
napisał(a):
… Right. If we follow the way other languages do Automation API right now
the script written against Automation API would get its own separate JVM,
and every up/destroy/etc command would get a separate JVM as well. This
way global state is isolated, but JVM startup cost and overhead is paid
multiple times.
—
Reply to this email directly, view it on GitHub
<#30 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAL52WAZD7UF3GUZCXDH2LUZAYANANCNFSM5NJZD7NQ>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Decided on an approach with ThreadLocal+manual propagation in the WIP PR #323 |
FYI, the aforementioned PR was closed on May 2022. There doesn't seem to be any progress on this issue. |
You can help us prioritize this by upvoting and explaining your use case! Thank you! |
This issue is relevant again, so I will try to provide some context. Pulumi SDKs have a notion of Deployment, that helps coordinate communications with the engine and tracks deployment progression. As two examples: every resource constructor invokes a Therefore, an instance of Deployment has to be available to SDK classes like Resource and Output constructors. The problem is that those SDK objects are instantiated by a user in their code, and we don't provide a mechanism to pass an explicit Deployment-related context (as e.g. in Go). In our current implementation of the Java SDK, we use DeploymentInstanceHolder to resolve a Deployment, which is a singleton object. That works ok for Pulumi programs, because there is always a single instance of a Deployment that needs to exist in a given process. However, this is not the case for other scenarios:
This problem is not unique to Java, and for other languages we found language-specific solutions. For example, the closest "relative" of our Java SDK - .NET SDK - uses A prototype of this has been created in #323. The PR history isn't visible anymore but the code still exists in https://github.com/pulumi/pulumi-java/blob/1cfe305e348c672c7d0c896a4c4c3bf7057f2635, e.g. CurrentDeployment and its usage. We may need to revive that prototype and see if we can land it reliably. |
The code in #323 uses a ThreadLocal combined with wrapping all known callbacks received from the user to run in context where the ThreadLocal is set correctly. This works as you would expect for applyValue and other Output combinators, but it is not entirely foolproof and it would break down in advanced scenarios. For example, in scenarios where users obtain a raw CompletableFuture, for example from an invoke, and then attempt to do Pulumi operations in a callback where the ThreadLocal is not set correctly. This code would fail to look up the Deployment. future.thenAccept(result -> new Bucket()); More advanced scenarios where users manage their own threadpools could also be affected. At the time of writing #323 we thought it might be viable to accept this behavior and compensate with documentation pointing users to APIs they need to call to obtain a Deployment handle and pass it around explicitly for these advanced use cases. |
For invoke, we can wrap the result in a Future that resets the deployment. For a custom thread pool, no good solution short of providing a PulumiThreadPool helper. |
Hello!
Issue details
Global state is inherited from the C# translation. It primarily is a Deployment instance object and, indirectly, Stack. If this can be avoided by explicit param passing or other means, we get the ability for several Pulumi deployments coexisting peacefully in the same JVM process. While we do not know use cases for this yet, it may become desirable someday - just a general design sense.
Notes from Pawel (from #1):
Affected area/feature
The text was updated successfully, but these errors were encountered: