Mutiny



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!
CategoryStory Event
TypeStory
Linked to
Data ID150669

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]

ActionsRequirementsEffectsNotes
Cut them down!

Cowards! Villains! Damn them all!


Game note:Failure here means your game is over.

    Iron challenge ( 167 for 100% )
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.

    Triggers event:Lost With All Hands
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.

    -5 x Iron-50 x Terror~1/2 x Crew
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.

    Hearts challenge ( 334 for 100% )
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.

    Triggers event:Lost With All Hands
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.

    -10 x Hearts-20 x Terror-1 x Crew


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
Retrieved from 'https://sunlesssea.fandom.com/wiki/MUTINY!?oldid=54400'
  • 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 appropriately

  • Apache 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 result

  • io.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 application

  • example Dockerfile files for both native and jvm modes in src/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 io.smallrye.common.annotation.Blocking annotation.You can use @Blocking on a method, class or enable it for the whole application by annotated an Application class:

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:

Mutiny

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:artifactIdDescription

io.smallrye.reactive:smallrye-mutiny-vertx-core

Mutiny API for Vert.x Core

io.smallrye.reactive:smallrye-mutiny-vertx-mail-client

Mutiny API for the Vert.x Mail Client

io.smallrye.reactive:smallrye-mutiny-vertx-web-client

Mutiny API for the Vert.x Web Client

io.smallrye.reactive:smallrye-mutiny-vertx-mongo-client

Mutiny API for the Vert.x Mongo Client

io.smallrye.reactive:smallrye-mutiny-vertx-redis-client

Mutiny API for the Vert.x Redis Client

io.smallrye.reactive:smallrye-mutiny-vertx-cassandra-client

Mutiny API for the Vert.x Cassandra Client

io.smallrye.reactive:smallrye-mutiny-vertx-consul-client

Mutiny API for the Vert.x Consul Client

io.smallrye.reactive:smallrye-mutiny-vertx-kafka-client

Mutiny API for the Vert.x Kafka Client

io.smallrye.reactive:smallrye-mutiny-vertx-amqp-client

Mutiny API for the Vert.x AMQP Client

io.smallrye.reactive:smallrye-mutiny-vertx-rabbitmq-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:

  1. The injected Vert.x instance has the io.vertx.mutiny.core.Vertx type which is the Mutiny variant of Vert.x;

  2. 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 as sendAndAwait. 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 as writeAndForget. andForget is available for method returning a Uni.andForget indicates that you don’t need the resulting Uni 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.x ReadStream into a Multi

  • toBlockingIterable / toBlockingStream methods allowing to transform a Vert.x ReadStream into a blocking iterable or blocking java.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