Release Notes (2.0.x)
Apache Pekko 2.0.x releases support Java 17 and above.
2.0.0
Apache Pekko 2.0.0 is a new major release. Do not assume binary compatibility with Pekko 1.x: libraries built against Pekko 1.x need to be rebuilt against Pekko 2.0.0, and some code will need source changes. Please read the Migration Guide before upgrading.
Users who built and tested with the 2.0.0 milestone releases may find that the 2.0.0 release has further changes, so you should rebuild and retest against 2.0.0.
It could take months for the other Pekko modules, such as Pekko HTTP, Pekko Connectors, Pekko gRPC, Pekko Management and the persistence plugins, to have 2.0.0 releases. Until then, users might be able to use the 2.0.0 milestone releases of those modules with Pekko 2.0.0, but you should test very carefully before relying on this in production.
Many of the changes in this release were previewed in a series of milestone releases. See the GitHub milestones for 2.0.0-M1, 2.0.0-M2, 2.0.0-M3 and 2.0.0-M4 for a fuller list of changes. There was no 2.0.0-M5 release: the changes made after 2.0.0-M4 are listed in the 2.0.0-M5 GitHub milestone.
Some of the bug fixes listed below have also been backported to Pekko 1.x releases.
Main changes
- Java 17 is the new minimum version (Java 8 and 11 are no longer supported) (#1730, PR1967)
- Scala 2.12 support has been dropped. Pekko 2.0.0 is published for Scala 2.13 and Scala 3 (#39, PR1986)
- A lot of code that was deprecated in Pekko 1.x (and in Akka before that) has been removed - see the Removed section below
- Big change for Java DSL users due to the removal of
pekko.japi.Function(and related classes, such aspekko.japi.function.FIandJAPI) in favour ofpekko.japi.function.Functionand the otherpekko.japi.functiontypes. Lambdas should recompile ok but if you declared variables or functions explicitly, then you may need to change your imports (PR2001, PR2064, PR2078, PR2079, PR2143, PR2198) - Java APIs no longer leak Scala types: Scala
Future,Option,Tuple2and Scala collections have been replaced withCompletionStage,Optional,pekko.japi.Pairand Java collections in a number of Java DSL methods, including the pekko-persistence Java APIs (PR1419, PR2007, PR2009, PR2092, #2086, PR3378, PR3388, PR3677) - Added many Akka changes that have recently become Apache Licensed (up to and including Akka 2.9.0) - see the Ported from Akka section below
sun.misc.Unsafeis no longer used. The code has been migrated to use VarHandles (PR1892, PR1894, PR1990, PR1995, PR3007, PR3008)- Reflection usage in core modules has been replaced with MethodHandles/VarHandles where possible (PR3300, PR3312)
- New pekko-serialization-jackson3 module. Users who are happy with pekko-serialization-jackson, which uses Jackson 2, can stick with that (PR2348)
- Switch to
PEKKas the default magic header in pekko-remote Artery comms. See Changing TCP magic header for what this means for rolling updates (PR3425) - Java 21 and 25 support improvements, including virtual thread support for more dispatcher types and JDK-aware ForkJoinPool tuning (#2232, PR2169, PR2242, PR2871, PR2890)
- Java DSL methods across streams, stream-typed, actor-typed, cluster-sharding-typed, distributed-data, persistence-typed and the testkits now use wildcard bounds (
? super/? extends) on their function, graph and collection parameters, so Java code can pass functions, sources, sinks and collections typed over a supertype or subtype without casts orupcast. Collections of graphs (for example inSource.combine,zipNandmergeAll) and the events passed toEffect.persistnow accept anyjava.lang.Iterableinstead of onlyjava.util.List(PR3713, PR3714, PR3717, PR3718, PR3719, PR3720) - Added JSpecify nullness annotations to the Java DSL APIs of streams, persistence, actor-typed, cluster-sharding-typed and testkit (#2563, PR2617, PR2850, PR3380)
- Serialization improvements: predefined
JsonSerializableandCborSerializablemarker traits, zstd compression for the Jackson serializers and automatic binding of ScalaPB messages to the protobuf serializer - see the Additions and Ported from Akka sections below - A number of security hardening changes - see the Security Hardening section below
- A number of configuration defaults have changed. See the Configuration Changes section of the Migration Guide
Upgrade notes
Please read the Migration Guide before upgrading. It covers the breaking API changes, dependency changes (such as the Agrona 2.x --add-opens requirement) and the configuration defaults that have changed in Pekko 2.0.0.
Unless already waiting for the peer’s close_notify, cancelling a TLS operator’s transport output now reports SessionTruncated on its plaintext output if a session was established and the peer’s close_notify has not been processed, including when no inbound data is buffered or a renegotiation is in progress (PR3740). Previously this path could complete silently after discarding received records. Consumers using the TLS BidiFlow directly must handle SessionTruncated as well as SessionBytes. The Scala and Java Tcp.bindWithTls and Tcp.outgoingConnectionWithTls APIs filter out this signal and continue to expose ByteString streams. The final signal obeys backpressure; cancel the plaintext output too if it will no longer be consumed. See Stream IO for details.
Security Hardening
- Pekko Remote TLS: optional hostname verification for classic remoting, warnings when hostname verification is not enabled or when TLS is not used, a new keystore-password config, eager SSLContext initialization in Artery so that misconfiguration fails fast and support for multiple certificates in the rotating keys engine
ca-cert-file(PR3164, PR3200, PR3397, PR3398, PR3400, PR3479, PR3528) - Jackson
JsonTypeInfo.Id.MINIMAL_CLASSis now treated as dangerous, likeId.CLASS(PR3304) - Resolve, check and parse manifests more carefully in the Jackson serializers (PR3503)
- New
max-decompressed-sizelimit for Jackson payload decompression and for other compressed payloads (defaults to unlimited for Jackson) (PR3491, PR3502, #3504, PR3515, PR3597) - Support
unlimitedfor the Jackson stream-read constraints (PR3522) - Bound inbound Artery TCP frame length at framing (PR3492, PR3524)
- Bound nesting depth when deserializing enclosed payloads (PR3500)
- Bound the number of entries in an Artery compression table advertisement (PR3510)
- Bound compression-pointer hops in DNS name parsing (PR3490)
- Don’t resolve HOCON includes in config that arrived in a message (PR3505)
- Match actor selection wildcards without backtracking (PR3506)
- Reject messages whose parallel repeated protobuf fields disagree in length (PR3507)
- Bounds check the lookup table indexes in cluster gossip (PR3508)
- Don’t dereference a null superclass in the protobuf allow list check (PR3509)
- Bound persistence event replay batches (PR3325)
- Add
maxTotalBufferSizeto MergeHub for an aggregate queue bound (PR3392) - Check the remote deployment allow list before deserializing the constructor arguments of a remotely deployed actor (PR3493)
- Stop resolving a wire-supplied manifest class for serializers that declare
includeManifest = false, so a peer can no longer use them to drive class loading (PR3495)
Bug Fixes
Actors, dispatchers and logging
- High concurrency issues introduced when switching from
sun.misc.Unsafeto VarHandles (PR3007, PR3008) - Stop handing a reused
Mailboxobject to the fork-join dispatcher, which could permanently damage a ForkJoinPool work queue or stop a mailbox from running again.Mailboxno longer extendsForkJoinTask(#3613, #3620, PR3621, PR3628) - Stop dispatcher failure reporting from recursing into a
StackOverflowError(#3613, PR3622) - Keep colliding virtual nodes in ConsistentHash, so the ring no longer depends on the order in which nodes were added or removed. Routing only changes for keys that land on a colliding ring position, but during a rolling update nodes on 1.x and 2.x could route those few keys differently (PR3611)
- Fix reentrant BatchingExecutor execution (PR3331)
- Deliver stashed timer messages for UnboundedStash and UnrestrictedStash (PR3264, #3265)
- Clean up stopped FSM transition listeners (PR3096)
- Discard stale ReceiveTimeout after cancelReceiveTimeout to avoid NPE in actor-typed (PR3086)
- Suppress dead-letter logging during a terminating shutdown when disabled (PR3262)
- Expand Array arguments in MarkerLoggingAdapter log templates (PR3263)
- Resolve a
LogSourceforgetClassresults on Scala 3, soLogging(system, getClass)compiles (#1538, PR3609) - Keep the
StashBufferImplinstrumentation hooks from being inlined by the Scala 2.13 optimizer (PR3616) - Enforce resizer bounds and minimum pool size for AdjustPoolSize, including in ClusterRouterPool (#3253, PR3364, PR3393)
- Handle post-Java 8 constant pool entries in LineNumbers (PR3465)
- Make AbstractPersistentActorWithTimers and AbstractFSMWithStash subclassable from Java when using Scala 3 (PR3475)
- Use
Locale.ROOTfortoLowerCase/toUpperCasecalls (PR3159) - Fix ByteString1C serialization to use a SerializationProxy (PR2929)
- Fix ProducerController crash on restart with an empty unconfirmed buffer (durable queue) (#2760, PR2762)
Streams
- Fix close being called in cancel for statefulMap (PR2365, PR2385)
- Fix recoverWith on a failed stage (PR2631, PR2674, PR2712)
- Fix Source.combine with a single source and type-transforming fan-in strategies (PR2726)
- Fix close handling in unfoldResource and unfoldResourceAsync (avoid double close and delay close until a pending read completes) (PR3157, PR3172)
- MapAsyncPartitioned fixes: ordered stage completion after trailing resumed failures, parallel processing preserving order within a partition and a demand-resume deadlock (PR3009, #2886, PR3365)
- Await in-flight completion on partner termination in SinkRef (PR3016)
- Prevent double materialization of SourceRef and SinkRef (PR3114)
- Release references to completed stage logics and to the initial interpreter shell in GraphInterpreter to avoid memory retention (PR3030, PR3031, #3243)
- Fix the current message reported to supervision in timer stages (PR3294)
- Initialize timer stage deadlines in preStart instead of at construction (PR3111)
- Preserve throttler tokens on failed writes (PR3097)
- Notify BroadcastHub and PartitionHub consumers on materializer shutdown (#3345, PR3346, PR3347)
- Preserve StageActor demand across fused streams (#3459, PR3461)
- Handle unexpected stop of the TLS actor gracefully (PR2801)
- Wait for transport demand instead of failing with
Stuck in unwrap loopwhen TLS unwrap needs a wrap, in both TLS engines (#442, #3732, PR3734) - Fix deferred TLS output handling on inbound close and abort the TLS transport on session verification failure (PR3323, PR3324)
IO, TCP and DNS
- Harden async DNS request id handling (PR2960)
- Avoid NPE in the outbound TCP stage when upstream finishes before connect (PR3259)
- Close unregistered TCP channels on setup failure (PR3273)
- Close IO resources left open on abrupt or failing paths: the
resolv.conffile parser, theInputStreamofStreamConverters.fromInputStreamon abrupt termination and the Artery Aeron UDP port auto-selection channel (PR3532)
Remoting
- Classic remoting robustness fixes: ignore stale ACKs, harden EndpointReader against dispatch errors, resume the reader after a failed handoff and buffer messages during passive handoff (PR3158, PR3166, PR3173, PR3205, PR3361)
- Validate the full UniqueAddress in Artery system message ACK/NACK handling (PR3175)
- Bound Artery stream shutdown (PR3317)
- Distribute
ActorSelectionmessages across the Artery outbound lanes by target path, instead of sending them all to the same lane whenoutbound-lanesis greater than 1 (PR3092) - Use a Seq rather than a Set to hold TCP magic ByteStrings (PR3484)
Cluster and Cluster Sharding
- Release lease on shard stop, and log an error when the release fails (PR2738, #3705, PR3733)
- Stop cluster sharding entities stuck in passivation after a timeout (PR3573)
- Filter messages from the remember-entities store (PR3411)
- Recreate a sharding replicator that has stopped (for example because its durable store failed to load) when another entity type is started, instead of reusing the stopped replicator (PR3700)
- Support
java.math.BigInteger/BigDecimalin cluster-metrics (#3385, PR3382)
Persistence
- Replaying a replicated event sourced actor from a snapshot caused a bug (PR2372)
- Emit
DeletedDurableStatefor deleted durable state objects (PR2397) - Invoke lifecycle signal handlers during snapshot recovery (PR3358)
- Stop PersistentActor by default when the RecoveryCompleted handler fails (PR3359)
Testkit
- Return a proper non-cancelled Cancellable from StubbedActorContext.scheduleOnce (PR3268)
- The multi-node test conductor answers address queries asynchronously, so a bind failure fails the caller’s
Futureinstead of escaping the message handler (#3693, PR3707) - Allow overriding
testKitwith avalinScalaTestWithActorTestKit(#1140, PR3610)
Ported from Akka
These changes were copied from Akka releases (up to and including Akka 2.9.0) that are now available under the Apache License, version 2.0.
Actors and Actor Typed
- Optimize PropsAdapter, typed actor context and system adapter (PR2743, PR2750)
- Improve error message for actorOf on a typed ActorSystem (PR2798)
- Include sourceThread in the typed actor MDC (PR3357)
- Include the exception type in StatusReply toString when not text (PR3271)
- Support ActorSystem/ClassicActorSystemProvider serializer constructors and improve the error message (PR2948)
Streams
- Fine-grained stream error logging control (PR2805)
- Support default attributes on materializers (PR3647)
Remoting and DNS
- Handle Artery uid collisions gracefully: the colliding peer is quarantined and told that it is quarantined, and the handshake fails instead of leaving the association in a broken state. Artery system uids are also generated in a way that makes collisions much less likely (PR3652, PR3676)
- Include roundtrip latency and sequence number in the heartbeat debug log (PR2736)
- Auto-select SRV lookup for the name lookup if the entry looks like an SRV name (PR2745)
- DnsResolutionActor and in-flight request deduplication (PR2919)
Cluster, Cluster Sharding and Distributed Data
- ShardedDaemonProcess: throttle keep-alive messages and limit them to a subset of nodes (PR2734)
- Improve the cluster sharding StopShards coordinator command and fix the coordinator role (PR2783, PR2918)
- Disable ClusterShardingHealthCheck after a configured duration post member-up (PR2785)
- Remember entities throttling per region instead of per shard and improved DData remember entities logging and consistency (PR2786, PR2799)
- Add ScheduledClock to reduce nanoTime overhead in recency-based passivation (PR2766)
- Consistent-hashing shard allocation strategy (PR3270)
- Initialize the DistributedData extension from ExternalShardAllocationStrategy (PR2923)
- Make it possible to define the cluster
appVersionlater (PR2947) - Define a custom lease name for Cluster Sharding and Cluster Singleton (PR3648)
- Distributed Data: wildcard prefix subscriptions in the Replicator (PR2735)
- Use ClusterShuttingDown in the Distributed Data Replicator (PR2765)
- Report the effective timeout in the shard hand off stop warnings (PR3644)
Persistence
- Custom stash support in persistence-typed (PR2433)
- Run the DurableStateBehavior delete effect asynchronously like persist (PR2752)
- Snapshot retention: only-one-snapshot optimization and only one retention cycle in progress at a time (PR2767, PR2797)
- Add filtered, source and tags fields to typed EventEnvelope, EventsByPersistenceIdTyped queries and
withTaggerForState(PR2807, PR2920) - Add
withmethods to the typed queryEventEnvelope(PR3646) - Support for external transport of replicated events in Replicated Event Sourcing (PR2808)
- Runtime plugin configuration for DurableState (PR3058)
- FilteredPayload placeholder for filtered journal events (PR3275)
- Scalable fan-out persistence query abstraction (
EventsBySliceFirehoseQuery) andEventsBySliceStartingFromSnapshotsQuery(PR3277) - Add
SerializedEventfor writing events that are already serialized (PR3650) EventWriterimprovements: optionally fill sequence number gaps withFilteredPayload, fail waiting writes instead of restarting when the sequence number lookup fails, handle snapshot events and bypass the journal circuit breaker for the duplicate writes it relies on (PR3653)
Serialization
- Predefined
JsonSerializableandCborSerializablemarker traits in pekko-serialization-jackson and pekko-serialization-jackson3, bound tojackson-jsonandjackson-cbor(PR3649, PR3666) - Bind ScalaPB messages to the protobuf serializer when ScalaPB is on the classpath (PR3651, PR3665)
Testkit
- Unpersistent versions of persistent behaviors for testing, renamed to
PersistenceProbeBehavior(PR2456, PR2494) - Asking support in the typed BehaviorTestKit (PR2450, PR2453)
Other
- Other Akka 2.9.0 changes (PR3432)
Additions
Actors
- Add
ActorSystem.terminateAndAwaitandActorSystem.close(PR2096, PR2486) - Add
UntypedAbstractActorWithStash,UntypedAbstractActorWithUnboundedStashandUntypedAbstractActorWithUnrestrictedStash(PR2097) - Add actor-typed Java DSL
AbstractMatchingBehavior(#2108, PR2379) - Add logging variants for the Java DSL stash and timer actor base classes (#2520, PR3387)
- Add the timeout duration to the
ReceiveTimeoutmessage (PR3399) - Add
StatusReply.fromTryandStatusReply.fromCallable(PR2810, PR2812)
Streams
- Add
Sink.sourceandmaterializeIntoSourceoperators (#2222, PR2250, PR1831) - Add
Sink#countoperator (#2182, PR2244) - Add
onErrorResume(including Java DSL, SubFlow and SubSource variants) and more recover operators for the Java DSL (#2116, PR2120, PR2336, PR2337) - Add
onErrorContinueoperator (#2159, PR2322) - Add
doOnFirstoperator (#2183, PR2363) - Add
doOnCanceloperator (#2374, PR2375) - Add
gzipDecompressoperator, replacing the deprecatedgunzip(which has been removed) (PR2406) - Add
Compression.zstdandCompression.zstdDecompressoperators, with optional compression dictionaries and a configurable decompression window limit (ZstdDecompressionSettings.withWindowLogMax). zstd-jni is an optional dependency that you need to add yourself, and the window limit needs zstd-jni 1.5.7-25 or later (#2404, PR3639, PR3710, PR3721) - Add
Source.fromOptionandmapOptionoperators (#2408, #2403, PR2413, PR2414) - Add
Source.itemsand an array basedSource.apply(#2416, PR2424, PR2428, PR2429) - Add
withContextoperators (PR3199) - Add an
alsoTooverload with configurable cancellation propagation (PR3127) - Add supervision strategy support to more operators that accept user functions (
groupedWeightedWithin,batch,expandandextrapolate) and log supervision Resume/Restart in mapAsync operators (#3110, PR3124, PR3180, PR3184, PR3185) - Add an opt-in GraphStage based TLS engine (the actor based implementation remains the default). Later fixes drain plaintext already accepted when the plaintext output is cancelled (including after a TLS 1.3
close_notifyor KeyUpdate) and fall back to heap buffers when the TCP buffer pool is too small for the SSLEngine (PR2878, PR3727, PR3728, PR3731, PR3738)
Dispatchers and IO
- Add virtualize support for thread-pool-executor (including the blocking IO dispatcher) and support setting the starting number of virtual threads (#2163, PR2169, PR2242)
- Make ForkJoinPool
minimum-runnableconfigurable and auto-tune it on JDK 25+ (PR2871, PR2890) - Support the
SO_REUSEPORTsocket option (PR2915)
Java API utilities
- Add
andThenandcomposetopekko.japi.function.Function(#2144, PR2147) - Add a throwing boolean supplier,
sneakyThrowandOptionalUtilJava utilities (PR2199, PR2218, PR2464) - Add
CompletionStagesutility and maketimeoutCompletionStage/afterCompletionStageaccept Java Duration (PR2060, PR2063, PR2067)
Persistence
- Add
JournalPersistFailedandJournalPersistRejectedsignals (PR1961) - Add an AsyncWriteJournal option for disabling the Resequencer (PR2027)
Testkit
PersistenceTestKitReadJournaltag and slice queries support resuming from aTimestampOffset(#1765, PR3615)- Add
DurableStateBehaviorTestKit(PR3360) - The Java test kits now support JUnit Jupiter (JUnit 5 and 6). Pekko’s own Java tests have been migrated from JUnit 4 (#967, PR2289, PR2724, PR2865)
- Java DSL TestKit
shutdownActorSystemthat takes Java Duration params (#2226, PR2277)
Serialization
- Add zstd compression to the Jackson serializers (
compression.algorithm = zstd). zstd-jni is an optional dependency that you need to add yourself (PR3641)
Other
- Add
ByteString.endsWith,indexOfwith from and to,lastIndexOfSlice,copyToArrayanddecodeStringoverloads that read a sub-range without slicing, and makeByteString.copyToBuffer(buffer, offset)public (PR2271, PR2855, PR2862, PR2946, PR3464) - Add OSGi headers to pekko-pki and pekko-cluster-typed and compute OSGi imports for Pekko packages dynamically (PR2107, PR2112, PR2313)
- Add
LeaseHealthCheck, which checks that a lease implementation’s API is reachable by trying to acquire and release a test lease (PR3423) - Add Scala 3.8 and 3.9 compatibility (Pekko is still published using Scala 3.3 LTS) (PR3072, PR3073, PR3074, PR3295, PR3303)
Changes
API changes
- Make
SubFlowandSubSourcefinal classes and switch the type parameter order ofUnfoldResourceSourceandUnfoldResourceSourceAsync(PR615, PR616, PR619) - Remove the unnecessary empty parameter list from
watchTermination(#2376, PR2378) - Change
Futures#findand otherFuturesmethods to return JavaCompletionStage(#2008, PR2009) - Stream Java DSL now uses
pekko.japi.functiontypes throughout (#2118, PR2143) - Fix the Java DSL
SourceWithContext/FlowWithContextshape to usepekko.japi.Pair(#2510, PR3388) - Replace
scala.Tuple2withpekko.japi.PairinFSMTransitionHandlerBuilder(PR3378) - Use
CompletionStageand Java collections in the Java shard allocation strategy API (ShardCoordinator.AbstractShardAllocationStrategy) (PR3677) - Widen Java DSL function, graph and collection parameters with wildcard bounds, and accept
java.lang.Iterablefor collections of graphs and inEffect.persist(PR3713, PR3714, PR3717, PR3718, PR3719, PR3720) - In typed persistence (event sourcing and durable state, Scala and Java DSLs),
thenStopis only available on the newReplyEffectWithStopreturned byreply,noReply,thenReplyandthenNoReply, sostash().thenStop(), which discarded the stashed command without a reply, no longer compiles (PR3682) - Replace
immutable.Traversablein the public io and stream APIs (PR3467, PR3468) - Remove
ExecutorServiceFactoryProviderfromThreadPoolConfig(#2171, PR2175) - Replace the actor based fanout publisher runtime (
Sink.asPublisher(fanout = true)) with a GraphStage bridge (PR2874) - Remove the deprecated annotation from
recoverWithand undeprecate thegetFirst/getFirstAttributemethods (PR2119, PR3404) - Mark public sealed traits and abstract classes with
@DoNotInherit(#1270, PR3386) - Remove
@ApiMayChangefrom APIs that have proven stable, including the log markers,RotatingKeysSSLEngineProvider,ExternalShardAllocation,RetryFlow, theMaterializerStateAPI and the typed persistence query APIs (PR3607, PR3636, PR3656)
Removed legacy support
- Remove the Akka 2.6.4 rolling-migration manifests from ClusterMessageSerializer (PR3516)
- ClusterShardingSettings: remove backward-compat passivation code (PR3026)
- Remove the
ssl-configdependency (#2125, PR2127, PR2359) - Remove usage of
SecurityManager(#1970, PR2106)
Remoting and serialization
- Replace CountMinSketch with FastFrequencySketch in Artery compression (PR3023)
- Fail ActorSystem startup when both pekko-serialization-jackson and pekko-serialization-jackson3 are on the classpath. They register serializers with the same names and identifiers, so one would silently take over the other’s bindings (#3671, PR3673)
Build and code modernisation
- Use the better ByteBuffer cleaner available in Java 9+ (PR2020, PR2031)
- Code modernisation to use Java 17 language features and APIs (pattern matching instanceof, switch expressions, records, sealed types, collection factories, lambdas instead of anonymous inner classes) (#2083, #2201, PR2088, PR3188, PR3190, PR3191, PR3192, PR3193, PR3194, PR3379)
- Code modernisation for Scala 2.13 and Scala 3, using the standard
scala.jdkconverters instead of compat libraries (#2126, PR2205, PR2206, PR2236, PR3539) - Use
-Yfuture-lazy-valsfor Scala 3 builds (PR3059) - Fix many compiler, Scaladoc and Javadoc warnings (PR3283, PR3284, PR3285, PR3297, PR3330)
- Regenerated the protobuf source code using protoc 4.36 (PR2036, PR2335, PR3514)
- Validate legal files in packaged jars (PR3328)
Documentation
- Many documentation improvements, including a list of configuration changes in the migration guide, docs for the jackson3 module, the JUnit Jupiter test kit, custom Durable State store plugins, migrating off the deprecated
Source.queueoverloads and the removedPekkoSSLConfigAPIs, clearer typed actor and persistence lifecycle guidance, separate build tool (sbt, Maven, Gradle) and language selectors, and stream operator reference pages for previously undocumented operators (PR2391, PR2468, PR3274, PR3513, PR3583, PR3585, #3589, PR3590, PR3605, PR3654, PR3655, PR3658, PR3660, PR3661, PR3663, PR3664)
Performance
- SIMD within a register (SWAR) and VarHandle based ByteString search (
indexOf,lastIndexOf,indexOfSlice,contains) (#1264, #2150, PR2148, PR2306, PR2309, PR2838, PR2839, PR2863) - Other ByteString improvements: faster equality, concatenation, slicing, fragment lookup,
ByteStringBuilder.resultand multi-byte reads (PR2847, PR2924, PR3427, PR3428, PR3463, PR3471, PR3526) - Faster
UnsynchronizedByteArrayInputStreamusage (PR2300, PR3541) - Batch elements across internal async stream boundaries (PR3288, PR3296, #3459, PR3461)
- Optimize
Source.fromiterable,Source.future,Source.futureSourceandSource.applyfor Seq (PR2556, PR2560, PR2562) - Avoid substream materialization for value-presented sources in FlattenMerge and concat (PR2977, PR2978)
- GraphInterpreter hot path optimizations (PR2986, PR3119, PR3373)
- Stream materializer wiring and stage actor optimizations (PR3035, PR3062, PR3063)
- Optimize
Source.actorRefwith a direct-push fast path (PR3091) - Avoid Holder allocation in ordered mapAsync for already-completed futures (PR3018)
- Use an ArrayList in BroadcastHub (PR2262)
- Avoid quadratic cursor scans in fanout publishers (
Sink.asPublisher(fanout = true)) with many subscribers (PR3730) - Reduce receive-timeout state allocations and avoid type pollution (PR3332, PR3334)
- Validate actor path elements without
String.charAt(PR3542) - Avoid redundant bounds checks on
ByteStringindexed reads inByteStringParserand the DNS over TCP client (PR3533) - Defer log message rendering in typed persistence and the testkit log capturing by using slf4j placeholders (PR3537)
Removed
Much of the code that was deprecated in Pekko 1.x (and in Akka before that) has been removed. At a high level:
- Typed Actors (the classic
TypedActorAPI, not Pekko Typed) (#571, PR1969) ActorMaterializerclass and deprecated materializer,ActorMaterializerSettings,IOSettingsandStreamRefSettingsfactory methods (PR2011, PR2137, PR3293)- Deprecated stream operators and methods, including the Future based operators, stream converters,
OverflowStrategy.dropNew,SubstreamCancelStrategy, the oldsplitWhen/splitAfteroverloads,GraphStage.onDownstreamFinish()and the stream testkitprobemethods (PR1958, PR1996, PR2006, PR2012, PR2017, PR2073, PR2129, PR2146, PR2440, PR3292) - Deprecated actor, scheduler, testkit, remote, cluster, cluster-sharding (including old backoff classes and settings), distributed-data, persistence and DNS code (PR1945, PR1959, PR1965, PR1966, PR1969, PR1981, PR1983, PR2018, PR2023, PR2037, PR3289)
pekko.japi.Functionand related classes,FI,JAPIandpekko.japi.Option(PR2007, PR2078, PR2079, PR2193)- Scala version compatibility classes in
pekko.util(such asccompat,FutureConverters,OptionConverters,ExecutionContexts.parasitic) as Pekko now uses the Scala 2.13 standard library equivalents (PR2207, PR2208, PR2212, PR2234, PR2582) - Internal and unused code such as
ReentrantGuard,AbruptIOTerminationException,ActorProcessorand the classic remotingdisassociatemethods (#2160, PR2065, PR2072, PR2074, PR2161, PR3027) - The
ssl-configconfiguration sections (PR2359) - Support for removing Cluster Sharding coordinator data stored by Akka 2.3.x from
RemoveInternalClusterShardingData(PR3608)
Deprecations
Some additional APIs have been deprecated and will be removed in a future release.
org.apache.pekko.dispatch.Futures(#1417, PR3377)Patterns.timeout(PR2050)Source.futurein the Java DSL (PR2593)BalancingDispatcherConfigurator, which is now also marked as internal API (#3384, PR3391)- The
pekko.persistence.dispatchersconfiguration (PR2482)
Dependency Changes
- Java 17 is the minimum supported version
- Scala 2.13.18 and 3.3.9
- netty 4.2.19.Final
- jackson 2.22.4 (pekko-serialization-jackson) and jackson 3.2.4 (pekko-serialization-jackson3)
- aeron 1.54.0 and agrona 2.7.0
- protobuf-java 4.36.2
- lightbend/config 1.4.9
- slf4j 2.0.20
- lz4-java 1.12.1 (
at.yawk.lz4:lz4-java) - zstd-jni 1.5.7-25 (optional, only needed for the zstd stream operators and zstd compression in the Jackson serializers)
- junit-jupiter 6.1.3
- The
ssl-configdependency has been removed
Known Issues
- MergeLatest does not backpressure upstreams and buffers without bound (#3592).
Serialization.deserializewith serializer id 0 (NullSerializer) and a non-empty manifest returnsSuccess(null), whatever the bytes contain (#3749). Previously this failed withNotSerializableExceptionunless the manifest named a loadable class. Id 0 is a common default for a missing int value, so a corrupt stored record can load as anullpayload instead of failing. As a workaround, code that reads serializer ids from storage should treat a record with id 0 and non-empty bytes as a failure before callingdeserialize.NullSerializeronly ever writes an empty array, so such a record cannot be valid.