Skip to content

fix: Use new model for Quarkus dev services#180

Open
holly-cummins wants to merge 1 commit intomicrocks:new-dev-services-apifrom
holly-cummins:new-dev-services-api
Open

fix: Use new model for Quarkus dev services#180
holly-cummins wants to merge 1 commit intomicrocks:new-dev-services-apifrom
holly-cummins:new-dev-services-api

Conversation

@holly-cummins
Copy link
Contributor

@holly-cummins holly-cummins commented Jan 13, 2026

Resolves #161. Builds on https://github.com/microcks/microcks-quarkus/tree/new-dev-services-api.

This is a big diff, sorry! It will need Quarkus 3.31 (not yet released) and quarkusio/quarkus#51025 (not yet merged).

Here's what I've done:

  • In line with the new model, made all containers start after build time (but before runtime, in a kind of in-between state)
  • Updated the dev ui card initialisation to read/send the url at runtime
  • Made three dev services for the three containers. This wasn't strictly necessary. It does have the impact that three services show on the dev services panel in the dev ui, which might be desirable or not. We should perhaps implement support for multi-container services in the dev UI panel, if we don’t have it already. If three services isn't wanted, you'd need to make a ThreeContainerContainer class, configure it with the information about what containers should be included, and have that container start all three containers in its start() method. I didn't find a strong reason why any of the containers needed to be started first or access each other's config, but if I understood wrong, that might be a reason to go for a single service.
  • Used a brand new API to indicate that the minion container needs to be started after the Kafka container, and to pass through the kafka config. The Kafka config wouldn't be available through other mechanisms like Config.getConfig() at the time when the minion container is starting
  • I removed the static aPostmanCollectionIsPresent because static variables in processors are a bad idea; in this case the variable was only initialised in the poststartup hook, but it was used in a build step, which made the problem obvious.
  • Removed all static variables (processors shouldn't have static variables, but they used to be needed to make dev services work), and all manual management of the dev services lifecycle and re-use logic (it's done centrally)
  • As a side effect of getting rid of statics, I moved the scanning logic to their own classes, so that the results of scanning could be turned into a build item. This meant that the scanning could be separated into a 'scanning' phase, done at build time, and an 'applying' phase, which is done after the services start
  • I added more scaffolding to support multiple containers, partly to ensure that the build steps were only invoked if a container was available, and partly because comments indicated that will be wanted in the future anyway. (The build step chaining is a nice mechanism for only doing work if pre-conditions are met, but if a build step declares a SimpleBuildItem, the docs say it has to return one or it’s an error.)
  • I removed the Recorder, because it didn't seem necessary

With all this, the tests in quarkus-microcks-demo pass, and the dev ui looks about right. I did see some problems if I enable and then disable and then enable dev services but I don't know if that relates to my implementation here or is a more general issue.

I did undo the change @lbroudoux has in my fork of quarkus-microcks-demo to remove the quarkus. prefix from config, since this change seemed big enough on its own. :)

@holly-cummins holly-cummins changed the title Use new model for Quarkus dev services fix: Use new model for Quarkus dev services Jan 13, 2026
@lbroudoux
Copy link
Member

Thanks a lot @holly-cummins! Will dive into this in a few minutes.
A prerequisite is missing, though: the commit needs to be signed as it's a CNCF project.
Could you:

  1. In your local branch, run: git rebase HEAD~1 --signoff
  2. Force push your changes to overwrite the branch: git push --force-with-lease origin new-dev-services-api

Thanks a ton!

Signed-off-by: Holly Cummins <[email protected]>
@lbroudoux lbroudoux added kind/bug Something isn't working component/settings Relates to API/settings availables component/runtime Runtime behavior of dev service labels Jan 14, 2026
Copy link
Member

@lbroudoux lbroudoux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a few questions regarding build items vs. producers and the choice to have multiple MicrocksContainersEnsembleHostsBuildItem instances instead of just one. Can you help me better understand these points? Many thanks!

.serviceName(MicrocksQuarkusProcessor.FEATURE + "-" + config.serviceName() + "minion")
.serviceConfig(config) // the lifecycle of the postman container should be the same as of the microcks container
.startable(microcksSupplier)
.dependsOnConfig(KAFKA_BOOTSTRAP_SERVERS, MinionContainerStartable::setKafkaBootstrapServersFromDevService) // the minion shouldn't be started until kafka is started
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to have multiple dependsOnConfig() like this? Will we be able to reuse the same mechanism if we started a RabbitMQ dev services in addition of the Kafka one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is! Internally they're stored as a list, so you can add as many as you like.

You can declare them optional, which I've done here, so that the container will still be started even if the dependency never appears, or you can use the default call, which makes them mandatory. (Each dependency can be either optional or mandatory.)

Two caveats are:

  • For now, they don't chain, because no one has asked for that yet. So if (say) you made a new 'supervisor' container that depended on RabbitMQ and then the minion container depended on the supervisor container, they wouldn't start in three stages
  • The config that gets passed in is only from other dev services. So if, say, there was an external kafka service, the start() method would have to read that config directly. I'm not sure that's intuitive so I might change this, what do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that's intuitive so I might change this, what do you think?

I understood this point only when reading the start() method on line 456. Actually, the dependsOnConfig() name might not be very accurate here... Maybe something like computeIfDevServiceConfigPresent() (analogous to Map.computeIfAbsent()) would be more helpful regarding the conditional behavior on dev service config...
If start() is called in any case, I tend to think that it's not really a dependency

Naming is hard for sure!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If start() is called in any case, I tend to think that it's not really a dependency

The default is that start() wouldn't be called, but in the Microcks case, the minion needs to start even if there's no kafka config available, so I added the extra parameter for optional.

The confusion makes me think that neither the dependsOnConfig nor computeIfDevServiceConfigPresent name are quite right!

@lbroudoux lbroudoux added the keep-open Explicitily keep open label Feb 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/runtime Runtime behavior of dev service component/settings Relates to API/settings availables keep-open Explicitily keep open kind/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants