# Publisher

Published articles for Publisher.

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## 'Ship a good game, learn from it, and build from there:' Lessons from going indie after a decade at id Software

DevFeed: ['Ship a good game, learn from it, and build from there:' Lessons from going indie after a decade at id Software](<https://devfeed.tech/articles/ship-a-good-game-learn-from-it-and-build-from-there-lessons-from-going-indie-after-a-decade-at-id-software-15094.md>)

Original publisher: [Read original article](<https://www.gamedeveloper.com/production/-ship-a-good-game-learn-from-it-and-build-from-there-lessons-from-going-indie-after-a-decade-at-id-software>)

Author: Chris Kerr

Published: 2026-09-10T18:56:42Z

Content type: news

Language: en

Sources: [gamedeveloper](<https://devfeed.tech/sources/gamedeveloper.md>)

Topics: [Game Development](<https://devfeed.tech/topics/game-development.md>), [Development](<https://devfeed.tech/topics/development.md>), [cloud-infrastructure](<https://devfeed.tech/topics/cloud-infrastructure.md>)

Tags: [business](<https://devfeed.tech/tags/business.md>), [careers](<https://devfeed.tech/tags/careers.md>), [company](<https://devfeed.tech/tags/company.md>), [development](<https://devfeed.tech/tags/development.md>), [doom](<https://devfeed.tech/tags/doom.md>), [game-development](<https://devfeed.tech/tags/game-development.md>), [games](<https://devfeed.tech/tags/games.md>), [industry](<https://devfeed.tech/tags/industry.md>), [marketing](<https://devfeed.tech/tags/marketing.md>), [money](<https://devfeed.tech/tags/money.md>), [production](<https://devfeed.tech/tags/production.md>), [publisher](<https://devfeed.tech/tags/publisher.md>), [team](<https://devfeed.tech/tags/team.md>)

### AI overview

Game Developer interviews Tony Garza and Richard O'Neal about leaving id Software, founding the indie studio Turnkey Games, and developing the horror adventure Apart. They describe bootstrapping the company, growing the team gradually, controlling overhead, and directing spending toward development and essential business costs.

### Source excerpt

We sit down with Doom Eternal art director Tony Garza and fellow id alum Richard O'Neal to hear about their journey into the world of indie development through Turnkey Games.

## Indie devs and publishers hit in Gamescom equipment thefts

DevFeed: [Indie devs and publishers hit in Gamescom equipment thefts](<https://devfeed.tech/articles/indie-devs-and-publishers-hit-in-gamescom-equipment-thefts-15059.md>)

Original publisher: [Read original article](<https://www.gamedeveloper.com/business/indie-devs-and-publishers-hit-in-gamescom-equipment-thefts>)

Author: Bryant Francis

Published: 2026-08-31T14:58:21Z

Content type: news

Language: en

Sources: [gamedeveloper](<https://devfeed.tech/sources/gamedeveloper.md>)

Topics: [Steam Deck](<https://devfeed.tech/topics/steam-deck.md>), [Hardware](<https://devfeed.tech/topics/hardware.md>), [Security](<https://devfeed.tech/topics/security.md>)

Tags: [arena](<https://devfeed.tech/tags/arena.md>), [company](<https://devfeed.tech/tags/company.md>), [gamescom](<https://devfeed.tech/tags/gamescom.md>), [hardware](<https://devfeed.tech/tags/hardware.md>), [laptops](<https://devfeed.tech/tags/laptops.md>), [publisher](<https://devfeed.tech/tags/publisher.md>), [report](<https://devfeed.tech/tags/report.md>), [security](<https://devfeed.tech/tags/security.md>), [statement](<https://devfeed.tech/tags/statement.md>), [steam-deck](<https://devfeed.tech/tags/steam-deck.md>)

### AI overview

Independent developers and publishers reported laptops and Steam Decks stolen from Gamescom booths, prompting questions about the event's security practices and response.

### Source excerpt

Thieves obtained access to Gamescom's Indie Arena and business area and stole a number of laptops and Steam Decks from smaller exhibitors.

## Journey maker thatgamecompany announces thatgamepublisher

DevFeed: [Journey maker thatgamecompany announces thatgamepublisher](<https://devfeed.tech/articles/journey-maker-thatgamecompany-announces-thatgamepublisher-15061.md>)

Original publisher: [Read original article](<https://www.gamedeveloper.com/business/journey-maker-thatgamecompany-announces-thatgamepublisher>)

Author: Nicole Carpenter

Published: 2026-08-25T14:10:19Z

Content type: news

Language: en

Sources: [gamedeveloper](<https://devfeed.tech/sources/gamedeveloper.md>)

Topics: [Publishing](<https://devfeed.tech/topics/publishing.md>)

Tags: [community](<https://devfeed.tech/tags/community.md>), [funding](<https://devfeed.tech/tags/funding.md>), [games](<https://devfeed.tech/tags/games.md>), [indie-developers](<https://devfeed.tech/tags/indie-developers.md>), [marketing](<https://devfeed.tech/tags/marketing.md>), [publisher](<https://devfeed.tech/tags/publisher.md>), [strategy](<https://devfeed.tech/tags/strategy.md>)

### AI overview

thatgamecompany, the developer of Journey and Sky: Children of the Light, has launched thatgamepublisher, a publishing department funded by profits from Sky. It has signed a couple of unreleased games and offers funding, marketing, community, and strategy services to game teams of varying sizes and at different development stages.

### Source excerpt

Profit from Sky: Children of the Light will support the initiative.

## An Interactive Study of Publish/Subscribe Messaging for Event-Driven Backend Systems

DevFeed: [An Interactive Study of Publish/Subscribe Messaging for Event-Driven Backend Systems](<https://devfeed.tech/articles/what-is-pub-sub-17831.md>)

Original publisher: [Read original article](<https://encore.dev/blog/pubsub>)

Author: Ivan Cernja

Published: 2026-04-24T00:00:00Z

Content type: tutorial

Language: en

Sources: [Encore Updates](<https://devfeed.tech/sources/encore-updates.md>)

Topics: [Publish-subscribe pattern](<https://devfeed.tech/topics/pubsub.md>), [Messaging](<https://devfeed.tech/topics/messaging.md>), [Back end](<https://devfeed.tech/topics/backend.md>), [distributed-systems](<https://devfeed.tech/topics/distributed-systems.md>), [event driven](<https://devfeed.tech/topics/event-driven.md>)

Tags: [decoupling](<https://devfeed.tech/tags/decoupling.md>), [developers](<https://devfeed.tech/tags/developers.md>), [distributed-systems](<https://devfeed.tech/tags/distributed-systems.md>), [event-driven](<https://devfeed.tech/tags/event-driven.md>), [events](<https://devfeed.tech/tags/events.md>), [flow](<https://devfeed.tech/tags/flow.md>), [messaging](<https://devfeed.tech/tags/messaging.md>), [patterns](<https://devfeed.tech/tags/patterns.md>), [publisher](<https://devfeed.tech/tags/publisher.md>), [subscriber](<https://devfeed.tech/tags/subscriber.md>)

### AI overview

An interactive tutorial explains publish/subscribe messaging by contrasting it with direct service calls. It shows how topics decouple publishers from subscribers, support fan-out, and let subscribers process messages independently, including when downstream services are unavailable.

### Source excerpt

An interactive study of publish/subscribe messaging

## The city of systems: Temporal, Kafka, and Nexus

DevFeed: [The city of systems: Temporal, Kafka, and Nexus](<https://devfeed.tech/articles/the-city-of-systems-temporal-kafka-and-nexus-35758.md>)

Original publisher: [Read original article](<https://temporal.io/blog/city-of-systems-temporal-kafka-nexus>)

Author: Tao Guo

Published: 2025-12-10T00:00:00Z

Content type: article

Language: en

Sources: [Temporal Blog](<https://devfeed.tech/sources/temporal-blog.md>)

Topics: [Kafka](<https://devfeed.tech/topics/kafka.md>), [Event-Streaming](<https://devfeed.tech/topics/event-streaming.md>), [distributed-systems](<https://devfeed.tech/topics/distributed-systems.md>)

Tags: [distributed-systems](<https://devfeed.tech/tags/distributed-systems.md>), [event-streaming](<https://devfeed.tech/tags/event-streaming.md>), [kafka](<https://devfeed.tech/tags/kafka.md>), [partitions](<https://devfeed.tech/tags/partitions.md>), [publisher](<https://devfeed.tech/tags/publisher.md>), [queues](<https://devfeed.tech/tags/queues.md>), [streaming](<https://devfeed.tech/tags/streaming.md>), [subscriber](<https://devfeed.tech/tags/subscriber.md>), [temporal-voices](<https://devfeed.tech/tags/temporal-voices.md>)

### AI overview

The article presents Temporal, Kafka, and Nexus as complementary building blocks for distributed systems. It explains Kafka's publisher-subscriber model, consumer groups, and partitions, while noting that its high-volume event broadcasting can be vulnerable to lost signals and stalled processing.

### Source excerpt

Temporal, Kafka, and Nexus create the blueprint for great distributed systems, balancing high-speed event streaming with guaranteed certainty.

## Java 9 Flow API: taking and skipping

DevFeed: [Java 9 Flow API: taking and skipping](<https://devfeed.tech/articles/java-9-flow-api-taking-and-skipping-24812.md>)

Original publisher: [Read original article](<https://akarnokd.blogspot.com/2017/09/java-9-flow-api-taking-and-skipping.html>)

Author: David Karnok (noreply@blogger.com)

Published: 2017-09-30T20:44:00Z

Content type: tutorial

Language: en

Sources: [Akarnokd - Advanced RxJava](<https://devfeed.tech/sources/akarnokd-advanced-rxjava.md>)

Topics: [Java 9](<https://devfeed.tech/topics/java-9.md>), [API](<https://devfeed.tech/topics/api.md>), [reactive](<https://devfeed.tech/topics/reactive.md>)

Tags: [api](<https://devfeed.tech/tags/api.md>), [flow](<https://devfeed.tech/tags/flow.md>), [flow-api](<https://devfeed.tech/tags/flow-api.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [java-9](<https://devfeed.tech/tags/java-9.md>), [jdk](<https://devfeed.tech/tags/jdk.md>), [publisher](<https://devfeed.tech/tags/publisher.md>), [reactive](<https://devfeed.tech/tags/reactive.md>), [reactive-streams](<https://devfeed.tech/tags/reactive-streams.md>), [skip](<https://devfeed.tech/tags/skip.md>), [skipwhile](<https://devfeed.tech/tags/skipwhile.md>), [streams](<https://devfeed.tech/tags/streams.md>), [subscriber](<https://devfeed.tech/tags/subscriber.md>), [subscription](<https://devfeed.tech/tags/subscription.md>), [take](<https://devfeed.tech/tags/take.md>), [takeuntil](<https://devfeed.tech/tags/takeuntil.md>), [takewhile](<https://devfeed.tech/tags/takewhile.md>)

### AI overview

A tutorial on implementing take and skip-style operators with Java 9's Flow API. It explains how to limit a flow, cancel the upstream subscription when the limit is reached, complete the downstream subscriber, handle terminal events, and account for backpressure behavior.

### Source excerpt

Introduction Limiting or skipping over parts of a flow is a very common task: either we are only interested in the first N items or we don't care about the first N items. Sometimes, N is unknown but we can decide, based on the current item, when to stop relaying items or, in contrast, when to start relaying items. Take(N) In concept, limiting a flow to a certain size should be straightforward: count the number of items received via onNext and when the limit is reached, issue a cancel() towards the upstream and onComplete() towards the downstream. public static <T> Flow.Publisher<T> take(Flow.Publisher<T> source, long n) { return new TakePublisher<>(source, n); } The operator's implementation requires little state: static final class TakeSubscriber<T> implements Flow.Subscriber<T> { final Flow.Subscriber<? super T> downstream; Flow.Subscription upstream; long remaining; TakeSubscriber( Flow.Subscriber<? super> downstream, long n) { this.downstream = downstream; this.remaining = n; } @Override public void onSubscribe(Flow.Subscription s) { // TODO implement } @Override public void onNext(T item) { // TODO implement } @Override public void onError(Throwable throwable) { // TODO implement } @Override public void onComplete() { // TODO implement } } In its simplest form, there is no need for intercepting the request() and cancel() calls from the downstream: these can be passthrought, however, since the operator has to stop the sequence upon reaching the limit (remaining == 0), the upstream's Flow.Subscriber has to be stored. @Override public void onSubscribe(Flow.Subscription s) { this.upstream = s; downstream.onSubscribe(s); } In onSubscribe, we only have to store the Flow.Subscription and forward it to the downstream. @Override public void onNext(T item) { long r = remaining; if (r > 0L) { remaining = --r; downstream.onNext(item); if (r == 0) { upstream.cancel(); downstream.onComplete(); } } } While remaining is positive, we decrement it and save it into its field foll

## Java 9 Flow API: arbitration and concatenation

DevFeed: [Java 9 Flow API: arbitration and concatenation](<https://devfeed.tech/articles/java-9-flow-api-arbitration-and-concatenation-24807.md>)

Original publisher: [Read original article](<https://akarnokd.blogspot.com/2017/09/java-9-flow-api-arbitration-and.html>)

Author: David Karnok (noreply@blogger.com)

Published: 2017-09-27T12:55:00Z

Content type: tutorial

Language: en

Sources: [Akarnokd - Advanced RxJava](<https://devfeed.tech/sources/akarnokd-advanced-rxjava.md>)

Topics: [Java 9](<https://devfeed.tech/topics/java-9.md>), [Java](<https://devfeed.tech/topics/java.md>), [API](<https://devfeed.tech/topics/api.md>)

Tags: [api](<https://devfeed.tech/tags/api.md>), [arbiter](<https://devfeed.tech/tags/arbiter.md>), [arbitration](<https://devfeed.tech/tags/arbitration.md>), [concat](<https://devfeed.tech/tags/concat.md>), [concatenation](<https://devfeed.tech/tags/concatenation.md>), [concurrent](<https://devfeed.tech/tags/concurrent.md>), [event](<https://devfeed.tech/tags/event.md>), [flow](<https://devfeed.tech/tags/flow.md>), [flow-api](<https://devfeed.tech/tags/flow-api.md>), [java](<https://devfeed.tech/tags/java.md>), [java-9](<https://devfeed.tech/tags/java-9.md>), [jdk](<https://devfeed.tech/tags/jdk.md>), [onerrorresumenext](<https://devfeed.tech/tags/onerrorresumenext.md>), [publisher](<https://devfeed.tech/tags/publisher.md>), [repeat](<https://devfeed.tech/tags/repeat.md>), [request](<https://devfeed.tech/tags/request.md>), [retry](<https://devfeed.tech/tags/retry.md>), [submissionpublisher](<https://devfeed.tech/tags/submissionpublisher.md>), [subscriber](<https://devfeed.tech/tags/subscriber.md>), [subscription](<https://devfeed.tech/tags/subscription.md>), [subscriptionarbiter](<https://devfeed.tech/tags/subscriptionarbiter.md>)

### AI overview

This tutorial explains how to implement subscription arbitration for Java 9's Flow API when concatenating multiple publishers. It addresses stack growth, remaining-demand accounting, concurrent requests and cancellation, subscription switching, and produced-item tracking.

### Source excerpt

Introduction A very common task is to combine multiple sources, or more generally, start consuming a source once the previous source has terminated. The naive approach would be to simply call otherSource.subscribe(nextSubscriber) from onError or onComplete. Unfortunately, this doesn't work for two reasons: 1) it may end up with deep stacks due to a "tail" subscription from onError/onComplete and 2) we should request the remaining, unfulfilled amount from the new source that hasn't be provided by the previous source to not overflow the downstream. The first issue can be solved by applying a heavyweight observeOn in general and implementing a basic trampolining loop only for certain concrete cases such as flow concatenation to be described in this post. The second issue requires a more involved source: not only do we have to switch between Flow.Subscriptions from different sources, we have to make sure concurrent request() invocations are not lost and are routed to the proper Flow.Subscription along with any concurrent cancel() calls. Perhaps the difficulty is lessened by the fact that switching sources happens on a terminal event boundary only, thus we don't have to worry about the old source calling onNext while the logic switches to the new source and complicating the accounting of requested/emitted item counts. Enter SubscriptionArbiter. Subscription arbitration We have to deal with 4 types of potentially concurrent signals when arbitrating Flow.Subscriptions: A request(long) call from downstream that has to be routed to the current Flow.Subscription A cancel() call from downstream that has to be routed to the current Flow.Subscription and cancel any future Flow.Subscription. A setSubscription(Flow.Subscription) that is called by the current Flow.Subscriber after subscribing to any Flow.Publisher which is not guaranteed to happen on the same thread subscribe() is called (i.e., as with the standard SubmissionPublisher or our range() operator). A setProduced(long n)

## Java 9 Flow API: switching threads

DevFeed: [Java 9 Flow API: switching threads](<https://devfeed.tech/articles/java-9-flow-api-switching-threads-24811.md>)

Original publisher: [Read original article](<https://akarnokd.blogspot.com/2017/09/java-9-flow-api-switching-threads.html>)

Author: David Karnok (noreply@blogger.com)

Published: 2017-09-21T10:49:00Z

Content type: tutorial

Language: en

Sources: [Akarnokd - Advanced RxJava](<https://devfeed.tech/sources/akarnokd-advanced-rxjava.md>)

Topics: [Java](<https://devfeed.tech/topics/java.md>), [Java 9](<https://devfeed.tech/topics/java-9.md>), [API](<https://devfeed.tech/topics/api.md>), [reactive](<https://devfeed.tech/topics/reactive.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Concurrent Programming](<https://devfeed.tech/topics/concurrent-programming.md>)

Tags: [asynchronous](<https://devfeed.tech/tags/asynchronous.md>), [executor](<https://devfeed.tech/tags/executor.md>), [executorservice](<https://devfeed.tech/tags/executorservice.md>), [flow](<https://devfeed.tech/tags/flow.md>), [flow-api](<https://devfeed.tech/tags/flow-api.md>), [idea](<https://devfeed.tech/tags/idea.md>), [intellij](<https://devfeed.tech/tags/intellij.md>), [java](<https://devfeed.tech/tags/java.md>), [java-9](<https://devfeed.tech/tags/java-9.md>), [jvm](<https://devfeed.tech/tags/jvm.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [observeon](<https://devfeed.tech/tags/observeon.md>), [publisher](<https://devfeed.tech/tags/publisher.md>), [thread](<https://devfeed.tech/tags/thread.md>), [threading](<https://devfeed.tech/tags/threading.md>), [threads](<https://devfeed.tech/tags/threads.md>)

### AI overview

This tutorial explains how to switch execution between threads in reactive flows using Java 9's Flow API. It compares embedding thread switching in operators with a separate observeOn stage, then outlines an observeOn implementation based on Executor, asynchronous boundaries, bounded queues, and request management.

### Source excerpt

Introduction Ensuring certain computations happen on the right thread, usually off the main thread, is a very common development task when dealing with reactive flows. When building up tools for Java 9's Flow API, one can decide to add this thread-switching support to each operator directly - see the range() operator from the start of the series -, or have a standalone stage for this purpose. This is a tradeoff. Inlining thread switching avoids bogging down the source thread like the thread-stealing behavior of most of the queue-drain approach presented so far. A separate operator allows better composition and may even allow working with exotic asynchrony-providing components. The observeOn operator In Java, threading support is provided via the Executor, ExecutorService and ScheduledExecutorService-based API. Executor is is the most basic one of them which only provides a single execute(Runnable) method. This allows creating an Executor from a lambda: Executor trampoline = Runnable::run; Executor swing = SwingUtilities::invokeLater; Executor pool = ForkJoinPool.commonPool(); As the least common denominator, we'll use Executor in defining our observeOn operator: public static <T> Flow.Publisher<T> observeOn( Flow.Publisher<T> source, Executor exec, int prefetch) { return new ObserveOnPublisher<>(source, exec, prefetch); } Crossing an asynchronous boundary requires the temporary storage of an event until the other side can pick it up. The queue-drain approach can provide a nice bounded queue we can size with prefetch. In addition, the so-called stable-prefetch request management (shown in the mapFilter operator before) allows minimizing the overhead of requesting more items. First, let's see the skeleton of the operator's main Flow.Subscriber implementation: static final class ObserveOnSubscriber<T> implements Flow.Subscriber<T>, Flow.Subscription, Runnable { final Flow.Subscriber<? super T> downstream; final Executor exec; final int prefetch; final Queue<T> queue; F

## Java 9 Flow API: mapping and filtering in one stage

DevFeed: [Java 9 Flow API: mapping and filtering in one stage](<https://devfeed.tech/articles/java-9-flow-api-mapping-and-filtering-in-one-stage-24808.md>)

Original publisher: [Read original article](<https://akarnokd.blogspot.com/2017/09/java-9-flow-api-mapping-and-filtering.html>)

Author: David Karnok (noreply@blogger.com)

Published: 2017-09-02T14:33:00Z

Content type: tutorial

Language: en

Sources: [Akarnokd - Advanced RxJava](<https://devfeed.tech/sources/akarnokd-advanced-rxjava.md>)

Topics: [Java 9](<https://devfeed.tech/topics/java-9.md>), [reactive](<https://devfeed.tech/topics/reactive.md>), [API](<https://devfeed.tech/topics/api.md>), [Library](<https://devfeed.tech/topics/library.md>), [Open Source](<https://devfeed.tech/topics/open-source.md>)

Tags: [backpressure](<https://devfeed.tech/tags/backpressure.md>), [exception](<https://devfeed.tech/tags/exception.md>), [flow](<https://devfeed.tech/tags/flow.md>), [flow-api](<https://devfeed.tech/tags/flow-api.md>), [java-9](<https://devfeed.tech/tags/java-9.md>), [publisher](<https://devfeed.tech/tags/publisher.md>), [reactive](<https://devfeed.tech/tags/reactive.md>), [reactive-streams](<https://devfeed.tech/tags/reactive-streams.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>), [subscriber](<https://devfeed.tech/tags/subscriber.md>)

### AI overview

This article examines how to combine mapping and filtering into a single custom operator for Java 9 Flow API publishers. It discusses API design choices, handling mapped, dropped, failed, and completed items, and preserving Reactive Streams backpressure and protocol requirements.

### Source excerpt

Introduction In most reactive libraries, mapping and filtering can be done on a flow via separate operators map() and filter() respectively. One rare occasions, the functions to these operators would need to communicate with each other without sharing information in a flow-external manner and without using defer(). Such combined and standard mapFilter() operator doesn't exist and one has to write one of its own. Given that the Java 9 Flow API is brand new, one has to definitely write a custom operator for it as Java 9 itself doesn't provide any rich set of predefined operations on Flow.Publishers unlike its dual, the Stream API. Shameless advertising By the way, if you are looking for a Java 9 Flow-based, native and modern reactive library with rich set of operators, similar to RxJava 2 (even including some operators from its extension project), I happen to have one for you: Reactive4JavaFlow. It is free and open-source with the promising outlook that one day, it may form the basis for the next major RxJava version... MapFilter API design When the Reactive4Java library was first concieved in 2011, the first significant stumbling block was not the lack of lambdas in Java 6/7 but the lack of extension methods. C# had it and made Rx.NET conveniently extendable (assuming you managed to understand how to write operators for it as it wasn't open source at the time). Java still doesn't have any sign of ever getting extension methods, therefore, we either need a rich abstract base class, such as Flowable or Flux, or an utility class whose methods almost look like extension method definitions with the exception that the developer has to stack them on top of one another: import java.util.concurrent.*; import static FlowUtils.*; Flow.Publisher<String> f = timeout( mapFilter( new FlowRange(1, 10, Runnable::run), (v, e) -> { if (v % 2 == 0) { e.next(v.toString()) } if (v == 7) { e.complete(); } } ), 5, TimeUnit.MILLISECONDS ); When thinking about a combined map and filter operat

## Java 9 Flow API: asynchronous integer range source

DevFeed: [Java 9 Flow API: asynchronous integer range source](<https://devfeed.tech/articles/java-9-flow-api-asynchronous-integer-range-source-24805.md>)

Original publisher: [Read original article](<https://akarnokd.blogspot.com/2017/03/java-9-flow-api-asynchronous-integer.html>)

Author: David Karnok (noreply@blogger.com)

Published: 2017-03-05T13:08:00Z

Content type: tutorial

Language: en

Sources: [Akarnokd - Advanced RxJava](<https://devfeed.tech/sources/akarnokd-advanced-rxjava.md>)

Topics: [Java](<https://devfeed.tech/topics/java.md>), [Java 9](<https://devfeed.tech/topics/java-9.md>), [reactive](<https://devfeed.tech/topics/reactive.md>), [interfaces](<https://devfeed.tech/topics/interfaces.md>), [IntelliJ IDEA](<https://devfeed.tech/topics/intellij-idea.md>)

Tags: [asynchronous](<https://devfeed.tech/tags/asynchronous.md>), [backpressure](<https://devfeed.tech/tags/backpressure.md>), [coroutine](<https://devfeed.tech/tags/coroutine.md>), [flow](<https://devfeed.tech/tags/flow.md>), [flow-api](<https://devfeed.tech/tags/flow-api.md>), [java](<https://devfeed.tech/tags/java.md>), [java-9](<https://devfeed.tech/tags/java-9.md>), [jdk](<https://devfeed.tech/tags/jdk.md>), [operator](<https://devfeed.tech/tags/operator.md>), [publisher](<https://devfeed.tech/tags/publisher.md>), [range](<https://devfeed.tech/tags/range.md>), [reactive](<https://devfeed.tech/tags/reactive.md>), [reactive-streams](<https://devfeed.tech/tags/reactive-streams.md>), [request-management](<https://devfeed.tech/tags/request-management.md>), [source](<https://devfeed.tech/tags/source.md>), [submissionpublisher](<https://devfeed.tech/tags/submissionpublisher.md>), [subscriber](<https://devfeed.tech/tags/subscriber.md>), [subscription](<https://devfeed.tech/tags/subscription.md>), [trampoline](<https://devfeed.tech/tags/trampoline.md>), [varhandle](<https://devfeed.tech/tags/varhandle.md>)

### AI overview

A tutorial explores Java 9's Flow API and Reactive Streams interfaces by building an asynchronous integer range Publisher. It discusses composing Publishers, implementing Flow.Subscription, handling subscriber demand, and using IntelliJ 2017.1 EAP while the APIs were non-final.

### Source excerpt

Introduction Java 9 is becoming more reactive by introducing the Reactive-Streams interfaces under the parent class java.util.concurrent.Flow, enabling a new standard interoperation between future libraries built on top. There is almost no documentation beyond a underwhelming Oracle documentation and the SubmissionPublisher class' JavaDoc about how to write Publishers, Subscriptions and Subscribers under the Flow API. Plus the Oracle document practically concludes with see RxJava. Indeed, replacing the imports of org.reactivestreams.* with java.util.concurrent.Flow.* in RxJava 2's sources get's one a fully fledged reactive library but there seems to be one crucial expectation with components built on the Flow API: they have to be asynchronous at every stage. I could argue that the underlying concepts work totally fine in synchronous mode, but who am I to question the established definitions? Oh well, if the constraint is to be asynchronous, then let's do it in an asynchronous way. To see what it takes, we could start with a relatively simple source: an asynchronous integer range. Since both Java 9 and the IDE support is in non-final state, I recommend IntelliJ 2017.1 EAP for this "exercise". Asynchronous integer range source Unfortunately, Java 9 won't introduce any standard fluent API entry point with all the well loved map(), filter(), flatMap() etc. operators but one has to build individual Publishers and compose them stage-by-stage. This involves creating a parent Publisher class with the following typical pattern to host the input parameters of the flow to be observed: import java.util.concurrent.*; public final class FlowRange implements Flow.Publisher<Integer> { final int start; final int end; final Executor executor; public FlowRange(int start, int count, Executor executor) { this.start = start; this.end = start + count; this.executor = executor; } @Override public void subscribe(Flow.Subscriber<? super Integer> subscriber) { // TODO implement } } For brevit