The Mutiny on the Bounty The 1789 mutiny on the Bounty saw a rebellious crew hijack their ship and build their own island community. Commanded by William Bligh, HMS Bounty left England in December.
Mutiny Wine Room
- A brief introduction to Mutiny - the reactive programming library used by Quarkus. The difference between RESTEasy, RESTEasy Reactive and Reactive Routes.
- Find 29 ways to say MUTINY, along with antonyms, related words, and example sentences at Thesaurus.com, the world's most trusted free thesaurus.
- Mutiny - open rebellion against constituted authority (especially by seamen or soldiers against their officers) insurrection, revolt, uprising, rising, rebellion - organized opposition to authority; a conflict in which one faction tries to wrest control from another.
MUTINY! | |
---|---|
Category | Story Event |
Type | Story |
Linked to | |
Data ID | 150669 |
MUTINY! is a Sunless SeaStory Event.
Trigger conditions[edit | edit source]
MUTINY! is automatically triggered at zee if you have the following:
- Crew ≥ 4Terror ≥ 100
Story description[edit | edit source]
Fear and despair have destroyed the loyalty of your crew. Half of those who remain have taken up arms against you. You've taken shelter in the bridge, while their shots ring out around you.
Interactions[edit | edit source]
Actions | Requirements | Effects | Notes |
---|---|---|---|
Cut them down! Cowards! Villains! Damn them all! Game note:Failure here means your game is over. |
| Failed event | |
Treachery and despair You take cover with your loyalists, and hold them at bay as long as you can. One by one, you run out of ammunition. When they storm the bridge, you fight them hand-to-hand... to no avail. One of them smashes you through the glass of the bridge windows. You tumble to the deck as they shout in desperate victory, and land with a final crunch.
| |||
Successful event | |||
A costly victory A haze of blood and gunfire. Screams and imprecations. A man you knew with your knife in his heart. Rather quickly, it's over. You are drenched in blood and racked with wounds, and many of your crew are dead - but you stand victorious. Push the corpses of the mutineers into the sea, and press on for what little time remains to you.
| |||
Attempt to win them round You're their only hope of reaching home alive. Make them understand that. Game note:Failure here will, as it happens, also end the game. |
| Failed event | |
A final betrayal You think you're getting through to them. You see the lead mutineer nod in understanding, and lower his stolen rifle. You step out of cover, your arms raised... and a shot from his companion topples you. The false-stars above are the last thing you see. They're beautiful.
| |||
Successful event | |||
The long way home Home, hearth, sweethearts, grog. Mrs Plenty's Rubbery Lumps. If they stick with you, they'll see these things again. You see them nod and lower their weapons. The lead mutineer rushes you regardless, screaming in incoherent rage. You cut him down. You've won some time. But your confidence, and their trust in you, are failing.
|
Story events | |
---|---|
A New Recruit • Invitation to a Beheading • An Inspection by the Ministry of Public Decency • Returning to London • The First Clue • The House of the Question • The Revenue Men • The Rose and Tiger • The Trouble with Tomb-Colonists • The Vengeance of Jonah • The Venturer's Passage • The Web of Stone • The Wisp-Ways • Your Father's Bones: A Cold Trail (event) • Your Father's Bones: the Next Step |
- Bootstrapping the project
- Using Reactive APIs
Learn how to create a reactive application with Quarkus and explore the different reactive features offered by Quarkus.This guide covers:
A quick glance at the Quarkus engine and how it enables reactive
A brief introduction to Mutiny - the reactive programming library used by Quarkus
The difference between RESTEasy, RESTEasy Reactive and Reactive Routes
The bootstrap of a reactive application using RESTEasy Reactive
Creating a reactive JAX-RS endpoint (asynchronous, streams…)
Using reactive database access
Interacting with other reactive APIs
Prerequisites
less than 15 minutes
an IDE
JDK 8 or 11+ installed with
JAVA_HOME
configured appropriatelyApache Maven 3.6.2+
Solutions
We recommend that you follow the instructions from Bootstrapping project and onwards to create the application step by step.
However, you can go right to the completed example.
The solutions are located in the getting-started-reactive
and getting-started-reactive-crud
directories.
The multiple reactive facets of Quarkus
Quarkus is reactive.If you look under the hood, you will find a reactive engine powering your Quarkus application.This engine is Eclipse Vert.x (https://vertx.io).All network I/O passes through the non-blocking and reactive Vert.x engine.
Let’s take 2 examples to explain how it works.Imagine an incoming HTTP request.The (Vert.x) HTTP server, embedded in Quarkus, receives the request and then routes it to the application.If the request targets an imperative method (traditional JAX-RS, code annotated with @Blocking
…), the routing layer invokes the resource method in a worker thread and writes the response when the data is available.So far, nothing new or outstanding.The following picture depicts this behavior.In this case, the application code is invoked on a worker thread, and the business logic can block that thread.
But, if the HTTP request targets a reactive method (JAX-RS using RESTEasy Reactive, reactive routes, @Incoming
method not annotated with @Blocking
…), the routing layer invokes the route on the I/O thread giving lots of benefits such as higher concurrency and performance:
Because Quarkus uses the I/O thread to invoke your code, we save context-switches, avoid large thread pool management, and so improve the resource utilization.However, the code must NOT block that thread.Why? Because, I/O threads are used to handle multiple concurrent requests.As soon as the handling of a request cannot make progress because it needs to execute some I/O, it schedules these I/O and passes a continuation.It releases the thread which can handle another request.When the scheduled I/O complete, the continuation is executed, back on the I/O thread.
As a consequence, many Quarkus components are designed with reactive in mind, such as database access (PostgreSQL, MySQL, Mongo, etc.), application services (mail, template engine, etc.), messaging (Kafka, AMQP, etc.) and so on.But, to fully benefit from this model, the application code should be written in a non-blocking manner.That’s where having a reactive API is an ultimate weapon.
Mutiny - A reactive programming library
Mutiny On The Bounty Movie
Mutiny is a reactive programming library allowing to express and compose asynchronous actions.It offers two types:
io.smallrye.mutiny.Uni
- for asynchronous action providing 0 or 1 resultio.smallrye.mutiny.Multi
- for multi-item (with back-pressure) streams
Both types are lazy and follow a subscription pattern.The computation only starts once there is an actual need for it (i.e. a subscriber enlists).
Both Uni
and Multi
expose event-driven APIs: you express what you want to do upon a given event (success, failure, etc.).These APIs are divided into groups (types of operations) to make it more expressive and avoid having 100s of methods attached to a single class.The main types of operations are about reacting to failure, completion, manipulating items, extracting, or collecting them.It provides a smooth coding experience, with a navigable API, and the result does not require too much knowledge around reactive.
You may wonder about Reactive Streams (https://www.reactive-streams.org/).Multi
implements Reactive Streams Publisher
, and so implements the Reactive Streams back-pressure mechanism.Uni
does not implement Publisher
as the subscription to the Uni
is enough to indicate you are interested in the result.It is again with the idea of simpler and smoother APIs in mind as the Reactive Streams subscription/request ceremony is more complex.
Embracing the unification of reactive and imperative pillars from Quarkus, both Uni
and Multi
provide bridges to imperative constructs.For example, you can transform a Multi
into an Iterable
or await the item produced by a Uni
.
At that point, if you are a RxJava or a Reactor user, you may wonder how you can use your familiar Flowable
, Single
, Flux
, Mono
…Mutiny allows converting Unis
and Multis
from and to RX Java and Reactor types:
But, what about Vert.x?Vert.x APIs are also available using Mutiny types.The following snippet shows a usage of the Vert.x Web Client:
Last but not least, Mutiny has built-in integration with SmallRye Context Propagation so you can propagate transactions, traceability data, and so on in your reactive pipeline.
Bootstrapping the project
There are several ways to implement reactive application with Quarkus.In this guide we are going to use RESTEasy Reactive, an implementation of RESTEasy benefiting from the Quarkus reactive engine.By default, it invokes the HTTP endpoint on the I/O thread.
While it’s possible to use traditional RESTEasy, you would need to add the quarkus-resteasy-mutiny extension, and the method will still be invoked on a worker thread.So, while it would use reactive programming, it would still require worker threads, which defeats the purpose. |
The easiest way to create a new Quarkus project is to open a terminal and run the following command:
For Windows users
If using Powershell, wrap
-D
parameters in double quotes
It generates the following in ./getting-started-reactive
:
the Maven structure
an
org.acme.quickstart.ReactiveGreetingResource
resource exposed on/hello
an associated unit test
a landing page that is accessible on
http://localhost:8080
after starting the applicationexample
Dockerfile
files for bothnative
andjvm
modes insrc/main/docker
the application configuration file
Reactive JAX-RS resources
During the project creation, the src/main/java/org/acme/getting/started/ReactiveGreetingResource.java
file has been created with the following content:
It’s a very simple REST endpoint, returning 'Hello RESTEasy Reactive' to requests on '/hello'.As it uses RESTEAsy Reactive, this method is called on the I/O thread.
To instruct Quarkus to invoke this method on a worker thread, annotate it with the |
Let’s now create a ReactiveGreetingService
class with the following content:
Then, edit the ReactiveGreetingResource
class to match the following content:
The ReactiveGreetingService
class contains a straightforward method producing a Uni
.While, in this example, the resulting item is emitted immediately, you can imagine any async API producing a Uni
.We cover this later in this guide.
Once running, check you get the expected greeting message by opening http://localhost:8080/hello/greeting/neo.
Handling streams
So far, we only return an asynchronous result.In this section, we extend the application with streams conveying multiple items.These streams could come from Kafka or any other source of data, but to keep things simple, we just generate periodic greeting messages.
In the ReactiveGreetingService
, add the following method:
you may need to add the import io.smallrye.mutiny.Multi; and import java.time.Duration; statements. |
It generates a greeting message every second and stops after count
messages.
In the ReactiveGreetingResource
add the following method:
This endpoint streams the items to the client as a JSON Array.The name and number of messages are parameterized using path parameters.
We can also generate Server-Sent Event responses by returning a Multi
:
The only difference with the previous snippet is the produced type and the @RestSseElementType
annotation indicating the type of each event.As the @Produces
annotation defines SERVER_SENT_EVENTS
, JAX-RS needs it to knows the content type of each (nested) event.
You may need to add the import org.jboss.resteasy.reactive.RestSseElementType; statement. |
Using Reactive APIs
Using Quarkus reactive APIs
Quarkus provides many reactive APIs using the Mutiny model.In this section, we are going to see how you can use the Reactive PostgreSQL driver to interact with your database in a non-blocking and reactive way.
This application is interacting with a PostgreSQL database, so you need one:
Then, let’s configure our datasource.Open the src/main/resources/application.properties
and add the following content:
The 3 first lines define the datasource.The last line is going to be used in the application to indicate whether we insert a few items when the application gets initialized.
Now, let’s create our entity.Create the org.acme.reactive.crud.Fruit
class with the following content:
This entity contains a few fields and methods to find, update, and delete rows from the database.These methods return either Unis
or Multis
as the produced items are emitted asynchronously when the results have been retrieved.Notice that the reactive PostgreSQL client already provides Uni
and Multi
instances.So you only transform the results from the database into business-friendly objects.
For the purposes of initializing the database when the application starts, we will create a class named DBInit
with the following content:
Then, let’s use this Fruit
class in the FruitResource
.Edit the FruitResource
class to match the following content:
This resource returns Uni
and Multi
instances based on the result produced by the Fruit
class.
Using Vert.x clients
The previous example uses a service provided by Quarkus.Also, you can use Vert.x clients directly.
First of all, make sure the quarkus-vertx
extension is present. If not, activate the extension by executing the following command:
Or add quarkus-vertx
into your dependencies manually.
There is a Mutiny version of the Vert.x APIs.This API is divided into several artifacts you can import independently:
groupId:artifactId | Description |
---|---|
| Mutiny API for Vert.x Core |
| Mutiny API for the Vert.x Mail Client |
| Mutiny API for the Vert.x Web Client |
| Mutiny API for the Vert.x Mongo Client |
| Mutiny API for the Vert.x Redis Client |
| Mutiny API for the Vert.x Cassandra Client |
| Mutiny API for the Vert.x Consul Client |
| Mutiny API for the Vert.x Kafka Client |
| Mutiny API for the Vert.x AMQP Client |
| Mutiny API for the Vert.x RabbitMQ Client |
You can also check the available APIs on http://smallrye.io/smallrye-reactive-utils/apidocs/.
Let’s take an example.Add the following dependency to your application:
It provides the Mutiny API of the Vert.x Web Client.Then, you can use the web client as follows:
There are 2 important points:
The injected Vert.x instance has the
io.vertx.mutiny.core.Vertx
type which is the Mutiny variant of Vert.x;The Web Client is created from
io.vertx.mutiny.ext.web.client.WebClient
.
The Mutiny version of the Vert.x APIs also offers:
andAwait
methods such assendAndAwait
.andAwait
indicates that the caller thread is blocked until the result is available.Be aware not to block the event loop / IO thread that way.andForget
methods such aswriteAndForget
.andForget
is available for method returning aUni
.andForget
indicates that you don’t need the resultingUni
indicating the success or failure of the operation.However, remember that if you don’t subscribe, the operation would not be triggered.andForget
manages this for you and manage the subscription.toMulti
methods allowing to transform a Vert.xReadStream
into aMulti
toBlockingIterable
/toBlockingStream
methods allowing to transform a Vert.xReadStream
into a blocking iterable or blockingjava.util.Stream
Using RxJava or Reactor APIs
Mutiny provides utilities to convert RxJava 2 and Project Reactor types to Uni
and Multi
.
RxJava 2 converters are available in the following dependency:
So if you have an API returning RxJava 2 types (Completable
, Single
, Maybe
, Observable
, Flowable
), you can create Unis
and Multis
as follows:
You can also transform Unis
and Multis
into RxJava types:
Project Reactor converters are available in the following dependency:
So if you have an API returning Reactor types (Mono
, Flux
), you can create Unis
and Multis
as follows:
You can also transform Unis
and Multis
into Reactor types:
Using CompletionStages or Publisher API
If you are facing an API using CompletionStage
, CompletableFuture
, or Publisher
, you can convert back and forth.First, both Uni
and Multi
can be created from a CompletionStage
or from a Supplier<CompletionStage>
. For example:
On Uni
, you can also produce a CompletionStage
using subscribeAsCompletionStage()
that produces a CompletionStage
that would get the item or failure emitted by the Uni
.
You can also create Unis
and Multis
from instances of Publisher
using createFrom().publisher(Publisher)
.You can transform a Uni
into a Publisher
using toMulti
.Indeed, Multi
implements Publisher
.
What’s next?
Mutiny Nitrome
This guide is an introduction to reactive in Quarkus.There are plenty of Quarkus features that are already reactive.The following list gives you a few examples:
Mutiny Memorial
Using MongoDB and MongoDB with Panache
Interacting with Kafka and Interacting with AMQP