From ceb835f36eb0c7083384e66829d0aacfaeed7087 Mon Sep 17 00:00:00 2001 From: Julien Kronegg Date: Sun, 23 Apr 2023 13:23:03 +0200 Subject: [PATCH] Improved event bus performance using UUID generator selectable through SPI (#850) * feat: added documentation on UUID generators * fix: corrected documentation on UUID generators * Update content/docs/cucumber/state.md --------- Co-authored-by: Julien Kronegg Co-authored-by: M.P. Korstanje --- content/docs/cucumber/state.md | 54 ++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/content/docs/cucumber/state.md b/content/docs/cucumber/state.md index ec35f72c..60a0b0b3 100644 --- a/content/docs/cucumber/state.md +++ b/content/docs/cucumber/state.md @@ -460,6 +460,60 @@ The custom object factory can be configured using the `@CucumberOptions` annotat {{% block "ruby,javascript" %}} Using the Cucumber object factory is specific to JVM languages. {{% /block %}} +# The Event Bus +{{% block "java,kotlin" %}} + +Cucumber emits events on an event bus in many cases, e.g.: +- during the feature file parsing +- when the test scenarios are executed + +{{% /block %}} + +{{% block "ruby,javascript" %}} Using the Cucumber Event Bus is specific to JVM languages. {{% /block %}} + +## Configuring the UUID generator +{{% block "java,kotlin" %}} +Each event has a UUID as unique identifier. The UUID generator can be configured using the `cucumber.uuid-generator` property: + +| UUID generator | Features | Performance [Millions UUID/second] | Typical usage example | +|-------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `io.cucumber.core.eventbus.RandomUuidGenerator` |
  • Thread-safe
  • Collision-free in single-jvm/multi-jvm
| ~1 | Reports may be generated on different JVMs at the same time. A typical example would be one suite that tests against Firefox and another against Safari. The exact browser is configured through a property. These are then executed concurrently on different Gitlab runners. | +| `io.cucumber.core.eventbus.IncrementingUuidGenerator` |
  • Thread-safe
  • Collision-free in the same classloader
  • Almost collision-free in different classloaders / JVMs
  • UUIDs generated using the instances from the same classloader are sortable
| ~130 | For developers wanting high performance and accepting potential UUID collisions when running in different classloaders / JVMs setups. | + +The performance gain on real project depend on the feature size. + +When the generator is not specified, the `RandomUuidGenerator` is used. +{{% /block %}} + +{{% block "ruby,javascript" %}} Using the Cucumber UUID generator configuration is specific to JVM languages. {{% /block %}} + +## Defining your own UUID generator +{{% block "java,kotlin" %}} +When neither the `RandomUuidGenerator` nor the `IncrementingUuidGenerator` suits the project needs, a custom UUID generator can be defined. This is done using the following method: + +1. Creates a UUID class generator, e.g.: +```java +package mypackage.mysubpackage; +import io.cucumber.core.eventbus.UuidGenerator; +public class MyUuidGenerator implements UuidGenerator { + @Override + public UUID generateId() { + return ... + } +} +``` +2. Define the UUID generator as SPI using a file `META-INF/services/io.cucumber.code.eventbus.UuidGenerator` on the classpath (e.g. Maven `resources` directory) containing the generator class name: +```java +mypackage.mysubpackage.MyUuidGenerator +``` + +This UUID generator will override the default `RandomUuidGenerator`. + +When the `META-INF/services/...` file contains more than one UUID generator or when there are multiple `META-INF/services/...` on the classpath, the `cucumber.uuid-generator` property must be configured to select the desired generator. +{{% /block %}} + +{{% block "ruby,javascript" %}} Using the Cucumber custom UUID generator is specific to JVM languages. {{% /block %}} + # Databases There are several options to remove state from your database, to prevent leaking state between scenarios.