This is an automated email from the ASF dual-hosted git repository.

pjfanning pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pekko.git


The following commit(s) were added to refs/heads/main by this push:
     new 7244cd1c94 chore: remove @ApiMayChange from APIs that have proven 
stable (#3607)
7244cd1c94 is described below

commit 7244cd1c94b8d88633ac57bb116b36416c33ce47
Author: PJ Fanning <[email protected]>
AuthorDate: Fri Oct 9 16:59:56 2026 +0100

    chore: remove @ApiMayChange from APIs that have proven stable (#3607)
    
    Motivation:
    Several public APIs have been in use, unchanged, for several releases but 
are
    still marked @ApiMayChange, which tells users they may break in any release.
    
    Modification:
    Remove @ApiMayChange (and now-unused imports) from:
    - the log marker objects: ActorLogMarker, ClusterLogMarker, 
ShardingLogMarker,
      RemoteLogMarker
    - RotatingKeysSSLEngineProvider, dropping the scaladoc note that it may 
change
    - ExternalShardAllocation and the javadsl/scaladsl 
ExternalShardAllocationClient
    - stream CancellationStrategy and NestedMaterializationCancellationPolicy
      attributes, RetryFlow, and the MaterializerState stream snapshot API
    
    Result:
    These APIs are covered by the normal binary compatibility guarantees. There 
is
    no bytecode change.
    
    Tests:
    - sbt actor/remote/cluster/cluster-sharding/stream compile: passed
    - sbt <same modules>/mimaReportBinaryIssues: passed
    - scalafmt run on changed Scala files
    
    References:
    None - API stabilization
---
 .../scala/org/apache/pekko/actor/ActorLogMarker.scala |  2 --
 .../pekko/cluster/sharding/ShardingLogMarker.scala    |  2 --
 .../sharding/external/ExternalShardAllocation.scala   |  2 --
 .../javadsl/ExternalShardAllocationClient.scala       |  2 --
 .../scaladsl/ExternalShardAllocationClient.scala      |  2 --
 .../org/apache/pekko/cluster/ClusterLogMarker.scala   |  2 --
 .../org/apache/pekko/remote/RemoteLogMarker.scala     |  2 --
 .../tcp/ssl/RotatingKeysSSLEngineProvider.scala       |  6 ------
 .../scala/org/apache/pekko/stream/Attributes.scala    | 19 -------------------
 .../org/apache/pekko/stream/javadsl/RetryFlow.scala   |  3 ---
 .../org/apache/pekko/stream/scaladsl/RetryFlow.scala  |  3 ---
 .../pekko/stream/snapshot/MaterializerState.scala     | 17 +++++++----------
 12 files changed, 7 insertions(+), 55 deletions(-)

diff --git a/actor/src/main/scala/org/apache/pekko/actor/ActorLogMarker.scala 
b/actor/src/main/scala/org/apache/pekko/actor/ActorLogMarker.scala
index 22f13abeb5..b596830e36 100644
--- a/actor/src/main/scala/org/apache/pekko/actor/ActorLogMarker.scala
+++ b/actor/src/main/scala/org/apache/pekko/actor/ActorLogMarker.scala
@@ -14,7 +14,6 @@
 package org.apache.pekko.actor
 
 import org.apache.pekko
-import pekko.annotation.ApiMayChange
 import pekko.event.LogMarker
 
 /**
@@ -22,7 +21,6 @@ import pekko.event.LogMarker
  * No guarantee that it will remain binary compatible, but the marker names 
and properties
  * are considered public API and will not be changed without notice.
  */
-@ApiMayChange
 object ActorLogMarker {
 
   /**
diff --git 
a/cluster-sharding/src/main/scala/org/apache/pekko/cluster/sharding/ShardingLogMarker.scala
 
b/cluster-sharding/src/main/scala/org/apache/pekko/cluster/sharding/ShardingLogMarker.scala
index e71b0ab52f..38859ee31f 100644
--- 
a/cluster-sharding/src/main/scala/org/apache/pekko/cluster/sharding/ShardingLogMarker.scala
+++ 
b/cluster-sharding/src/main/scala/org/apache/pekko/cluster/sharding/ShardingLogMarker.scala
@@ -15,7 +15,6 @@ package org.apache.pekko.cluster.sharding
 
 import org.apache.pekko
 import pekko.actor.Address
-import pekko.annotation.ApiMayChange
 import pekko.annotation.InternalApi
 import pekko.event.LogMarker
 
@@ -24,7 +23,6 @@ import pekko.event.LogMarker
  * No guarantee that it will remain binary compatible, but the marker names 
and properties
  * are considered public API and will not be changed without notice.
  */
-@ApiMayChange
 object ShardingLogMarker {
 
   /**
diff --git 
a/cluster-sharding/src/main/scala/org/apache/pekko/cluster/sharding/external/ExternalShardAllocation.scala
 
b/cluster-sharding/src/main/scala/org/apache/pekko/cluster/sharding/external/ExternalShardAllocation.scala
index 117d480265..ede3b95dfe 100644
--- 
a/cluster-sharding/src/main/scala/org/apache/pekko/cluster/sharding/external/ExternalShardAllocation.scala
+++ 
b/cluster-sharding/src/main/scala/org/apache/pekko/cluster/sharding/external/ExternalShardAllocation.scala
@@ -22,13 +22,11 @@ import pekko.actor.ExtendedActorSystem
 import pekko.actor.Extension
 import pekko.actor.ExtensionId
 import pekko.actor.ExtensionIdProvider
-import pekko.annotation.ApiMayChange
 import 
pekko.cluster.sharding.external.internal.ExternalShardAllocationClientImpl
 
 /**
  * API May Change
  */
-@ApiMayChange
 final class ExternalShardAllocation(system: ExtendedActorSystem) extends 
Extension {
 
   private val clients = new ConcurrentHashMap[String, 
ExternalShardAllocationClientImpl]
diff --git 
a/cluster-sharding/src/main/scala/org/apache/pekko/cluster/sharding/external/javadsl/ExternalShardAllocationClient.scala
 
b/cluster-sharding/src/main/scala/org/apache/pekko/cluster/sharding/external/javadsl/ExternalShardAllocationClient.scala
index dcac16f810..a5064a17e9 100644
--- 
a/cluster-sharding/src/main/scala/org/apache/pekko/cluster/sharding/external/javadsl/ExternalShardAllocationClient.scala
+++ 
b/cluster-sharding/src/main/scala/org/apache/pekko/cluster/sharding/external/javadsl/ExternalShardAllocationClient.scala
@@ -18,7 +18,6 @@ import java.util.concurrent.CompletionStage
 import org.apache.pekko
 import pekko.Done
 import pekko.actor.Address
-import pekko.annotation.ApiMayChange
 import pekko.cluster.sharding.ShardRegion.ShardId
 import pekko.cluster.sharding.external.ShardLocations
 
@@ -27,7 +26,6 @@ import pekko.cluster.sharding.external.ShardLocations
  *
  * Not for user extension
  */
-@ApiMayChange
 trait ExternalShardAllocationClient {
 
   /**
diff --git 
a/cluster-sharding/src/main/scala/org/apache/pekko/cluster/sharding/external/scaladsl/ExternalShardAllocationClient.scala
 
b/cluster-sharding/src/main/scala/org/apache/pekko/cluster/sharding/external/scaladsl/ExternalShardAllocationClient.scala
index 6f57fda3cd..ba853e2771 100644
--- 
a/cluster-sharding/src/main/scala/org/apache/pekko/cluster/sharding/external/scaladsl/ExternalShardAllocationClient.scala
+++ 
b/cluster-sharding/src/main/scala/org/apache/pekko/cluster/sharding/external/scaladsl/ExternalShardAllocationClient.scala
@@ -18,7 +18,6 @@ import scala.concurrent.Future
 import org.apache.pekko
 import pekko.Done
 import pekko.actor.Address
-import pekko.annotation.ApiMayChange
 import pekko.cluster.sharding.ShardRegion.ShardId
 import pekko.cluster.sharding.external.ShardLocations
 
@@ -27,7 +26,6 @@ import pekko.cluster.sharding.external.ShardLocations
  *
  * Not for user extension
  */
-@ApiMayChange
 trait ExternalShardAllocationClient {
 
   /**
diff --git 
a/cluster/src/main/scala/org/apache/pekko/cluster/ClusterLogMarker.scala 
b/cluster/src/main/scala/org/apache/pekko/cluster/ClusterLogMarker.scala
index 7aabcbfba4..ad4441ee17 100644
--- a/cluster/src/main/scala/org/apache/pekko/cluster/ClusterLogMarker.scala
+++ b/cluster/src/main/scala/org/apache/pekko/cluster/ClusterLogMarker.scala
@@ -15,7 +15,6 @@ package org.apache.pekko.cluster
 
 import org.apache.pekko
 import pekko.actor.Address
-import pekko.annotation.ApiMayChange
 import pekko.annotation.InternalApi
 import pekko.cluster.sbr.DowningStrategy
 import pekko.event.LogMarker
@@ -25,7 +24,6 @@ import pekko.event.LogMarker
  * No guarantee that it will remain binary compatible, but the marker names 
and properties
  * are considered public API and will not be changed without notice.
  */
-@ApiMayChange
 object ClusterLogMarker {
 
   /**
diff --git 
a/remote/src/main/scala/org/apache/pekko/remote/RemoteLogMarker.scala 
b/remote/src/main/scala/org/apache/pekko/remote/RemoteLogMarker.scala
index 1c29f81009..1d9525ae80 100644
--- a/remote/src/main/scala/org/apache/pekko/remote/RemoteLogMarker.scala
+++ b/remote/src/main/scala/org/apache/pekko/remote/RemoteLogMarker.scala
@@ -15,7 +15,6 @@ package org.apache.pekko.remote
 
 import org.apache.pekko
 import pekko.actor.Address
-import pekko.annotation.ApiMayChange
 import pekko.event.LogMarker
 
 /**
@@ -23,7 +22,6 @@ import pekko.event.LogMarker
  * No guarantee that it will remain binary compatible, but the marker names 
and properties
  * are considered public API and will not be changed without notice.
  */
-@ApiMayChange
 object RemoteLogMarker {
 
   /**
diff --git 
a/remote/src/main/scala/org/apache/pekko/remote/artery/tcp/ssl/RotatingKeysSSLEngineProvider.scala
 
b/remote/src/main/scala/org/apache/pekko/remote/artery/tcp/ssl/RotatingKeysSSLEngineProvider.scala
index b047711ff0..8db8b08090 100644
--- 
a/remote/src/main/scala/org/apache/pekko/remote/artery/tcp/ssl/RotatingKeysSSLEngineProvider.scala
+++ 
b/remote/src/main/scala/org/apache/pekko/remote/artery/tcp/ssl/RotatingKeysSSLEngineProvider.scala
@@ -30,7 +30,6 @@ import scala.concurrent.duration._
 
 import org.apache.pekko
 import pekko.actor.ActorSystem
-import pekko.annotation.ApiMayChange
 import pekko.annotation.InternalApi
 import pekko.event.LogMarker
 import pekko.event.Logging
@@ -48,15 +47,10 @@ import com.typesafe.config.Config
  * Variation on ConfigSSLEngineProvider that will periodically reload the keys 
and certificates
  * from disk, to facilitate rolling updates of certificates.
  *
- * This class is still ApiMayChange because it can likely be further 
harmonized with
- * the standard ConfigSSLEngineProvider. Also the location and default values 
of the
- * configuration may change in future versions of Apache Pekko.
- *
  * This provider does not perform hostname verification, but instead allows 
checking
  * that the remote certificate has a subject name that matches the subject 
name of
  * the configured certificate.
  */
-@ApiMayChange
 final class RotatingKeysSSLEngineProvider(val config: Config, protected val 
log: MarkerLoggingAdapter)
     extends SSLEngineProvider {
 
diff --git a/stream/src/main/scala/org/apache/pekko/stream/Attributes.scala 
b/stream/src/main/scala/org/apache/pekko/stream/Attributes.scala
index 54f52d5796..b16b559a04 100644
--- a/stream/src/main/scala/org/apache/pekko/stream/Attributes.scala
+++ b/stream/src/main/scala/org/apache/pekko/stream/Attributes.scala
@@ -28,7 +28,6 @@ import scala.util.control.NonFatal
 
 import org.apache.pekko
 import pekko.actor.ActorSystem
-import pekko.annotation.ApiMayChange
 import pekko.annotation.DoNotInherit
 import pekko.annotation.InternalApi
 import pekko.annotation.InternalStableApi
@@ -457,9 +456,7 @@ object Attributes {
    * is to call `cancelStage` which shuts down the stage completely. The given 
strategy will allow customization of how
    * the shutdown procedure should be done precisely.
    */
-  @ApiMayChange
   final case class CancellationStrategy(strategy: 
CancellationStrategy.Strategy) extends MandatoryAttribute
-  @ApiMayChange
   object CancellationStrategy {
     private[stream] val Default: CancellationStrategy = 
CancellationStrategy(PropagateFailure)
 
@@ -481,7 +478,6 @@ object Attributes {
      * which arrive late at the other hand will just be ignored (that 
connection will have been cancelled already and also
      * the paths through which the error could propagates are already shut 
down).
      */
-    @ApiMayChange
     case object CompleteStage extends Strategy
 
     /**
@@ -501,14 +497,12 @@ object Attributes {
      * which arrive late at the other hand will just be ignored (that 
connection will have been cancelled already and also
      * the paths through which the error could propagates are already shut 
down).
      */
-    @ApiMayChange
     def completeStage: Strategy = CompleteStage
 
     /**
      * Strategy that treats `cancelStage` the same as `failStage`, i.e. all 
inlets are cancelled (propagating the
      * cancellation cause) and all outlets are failed propagating the cause 
from cancellation.
      */
-    @ApiMayChange
     case object FailStage extends Strategy
 
     /**
@@ -517,7 +511,6 @@ object Attributes {
      * Strategy that treats `cancelStage` the same as `failStage`, i.e. all 
inlets are cancelled (propagating the
      * cancellation cause) and all outlets are failed propagating the cause 
from cancellation.
      */
-    @ApiMayChange
     def failStage: Strategy = FailStage
 
     /**
@@ -530,7 +523,6 @@ object Attributes {
      *
      * This is a good default strategy.
      */
-    @ApiMayChange
     case object PropagateFailure extends Strategy
 
     /**
@@ -545,7 +537,6 @@ object Attributes {
      *
      * This is a good default strategy.
      */
-    @ApiMayChange
     def propagateFailure: Strategy = PropagateFailure
 
     /**
@@ -558,7 +549,6 @@ object Attributes {
      * such a delay. During this time, the stream will be mostly "silent", 
i.e. it cannot make progress because of backpressure,
      * but you might still be able observe a long delay at the ultimate source.
      */
-    @ApiMayChange
     final case class AfterDelay(delay: FiniteDuration, strategy: Strategy) 
extends Strategy
 
     /**
@@ -573,7 +563,6 @@ object Attributes {
      * such a delay. During this time, the stream will be mostly "silent", 
i.e. it cannot make progress because of backpressure,
      * but you might still be able observe a long delay at the ultimate source.
      */
-    @ApiMayChange
     def afterDelay(delay: java.time.Duration, strategy: Strategy): Strategy = 
AfterDelay(delay.toScala, strategy)
   }
 
@@ -594,7 +583,6 @@ object Attributes {
    * which arrive late at the other hand will just be ignored (that connection 
will have been cancelled already and also
    * the paths through which the error could propagates are already shut down).
    */
-  @ApiMayChange
   def cancellationStrategyCompleteState: CancellationStrategy.Strategy = 
CancellationStrategy.CompleteStage
 
   /**
@@ -603,7 +591,6 @@ object Attributes {
    * Strategy that treats `cancelStage` the same as `failStage`, i.e. all 
inlets are cancelled (propagating the
    * cancellation cause) and all outlets are failed propagating the cause from 
cancellation.
    */
-  @ApiMayChange
   def cancellationStrategyFailStage: CancellationStrategy.Strategy = 
CancellationStrategy.FailStage
 
   /**
@@ -618,7 +605,6 @@ object Attributes {
    *
    * This is a good default strategy.
    */
-  @ApiMayChange
   def cancellationStrategyPropagateFailure: CancellationStrategy.Strategy = 
CancellationStrategy.PropagateFailure
 
   /**
@@ -633,7 +619,6 @@ object Attributes {
    * such a delay. During this time, the stream will be mostly "silent", i.e. 
it cannot make progress because of backpressure,
    * but you might still be able observe a long delay at the ultimate source.
    */
-  @ApiMayChange
   def cancellationStrategyAfterDelay(
       delay: FiniteDuration,
       strategy: CancellationStrategy.Strategy): CancellationStrategy.Strategy =
@@ -651,7 +636,6 @@ object Attributes {
    * this [[Attribute]]: when set to true they will 'stash' the signal and 
later deliver it to the materialized nested flow
    * , otherwise these stages will immediately cancel without materializing 
the nested flow.
    */
-  @ApiMayChange
   final class NestedMaterializationCancellationPolicy 
private[NestedMaterializationCancellationPolicy] (
       val propagateToNestedMaterialization: Boolean,
       name: String)
@@ -659,7 +643,6 @@ object Attributes {
     override def toString: String = name
   }
 
-  @ApiMayChange
   object NestedMaterializationCancellationPolicy {
 
     /**
@@ -694,7 +677,6 @@ object Attributes {
    * nested flow materialization.
    * This applies to [[pekko.stream.scaladsl.FlowOps.flatMapPrefix]], 
[[pekko.stream.scaladsl.Flow.futureFlow]] and derived operators.
    */
-  @ApiMayChange
   def nestedMaterializationCancellationPolicyEagerCancellation(): 
NestedMaterializationCancellationPolicy =
     NestedMaterializationCancellationPolicy.EagerCancellation
 
@@ -705,7 +687,6 @@ object Attributes {
    * nested flow materialization. Once the nested flow is materialized it will 
be cancelled immediately.
    * This applies to [[pekko.stream.scaladsl.FlowOps.flatMapPrefix]], 
[[pekko.stream.scaladsl.Flow.futureFlow]] and derived operators.
    */
-  @ApiMayChange
   def nestedMaterializationCancellationPolicyPropagateToNested(): 
NestedMaterializationCancellationPolicy =
     NestedMaterializationCancellationPolicy.PropagateToNested
 
diff --git 
a/stream/src/main/scala/org/apache/pekko/stream/javadsl/RetryFlow.scala 
b/stream/src/main/scala/org/apache/pekko/stream/javadsl/RetryFlow.scala
index f45a2129b6..1e3a0ade12 100644
--- a/stream/src/main/scala/org/apache/pekko/stream/javadsl/RetryFlow.scala
+++ b/stream/src/main/scala/org/apache/pekko/stream/javadsl/RetryFlow.scala
@@ -19,7 +19,6 @@ import scala.jdk.DurationConverters._
 import scala.jdk.OptionConverters._
 
 import org.apache.pekko
-import pekko.annotation.ApiMayChange
 import pekko.japi.Pair
 import pekko.stream.scaladsl
 
@@ -46,7 +45,6 @@ object RetryFlow {
    * @param flow a flow to retry elements from
    * @param decideRetry retry condition decision function
    */
-  @ApiMayChange(issue = "https://github.com/akka/akka/issues/27960";)
   def withBackoff[In, Out, Mat](
       minBackoff: java.time.Duration,
       maxBackoff: java.time.Duration,
@@ -85,7 +83,6 @@ object RetryFlow {
    * @param flow a flow to retry elements from
    * @param decideRetry retry condition decision function
    */
-  @ApiMayChange(issue = "https://github.com/akka/akka/issues/27960";)
   def withBackoffAndContext[In, InCtx, Out, OutCtx, Mat](
       minBackoff: java.time.Duration,
       maxBackoff: java.time.Duration,
diff --git 
a/stream/src/main/scala/org/apache/pekko/stream/scaladsl/RetryFlow.scala 
b/stream/src/main/scala/org/apache/pekko/stream/scaladsl/RetryFlow.scala
index b0817f92fe..f607390f9e 100644
--- a/stream/src/main/scala/org/apache/pekko/stream/scaladsl/RetryFlow.scala
+++ b/stream/src/main/scala/org/apache/pekko/stream/scaladsl/RetryFlow.scala
@@ -16,7 +16,6 @@ package org.apache.pekko.stream.scaladsl
 import scala.concurrent.duration._
 
 import org.apache.pekko
-import pekko.annotation.ApiMayChange
 import pekko.stream.impl.RetryFlowCoordinator
 
 object RetryFlow {
@@ -49,7 +48,6 @@ object RetryFlow {
    * @param flow a flow to retry elements from
    * @param decideRetry retry condition decision function
    */
-  @ApiMayChange(issue = "https://github.com/akka/akka/issues/27960";)
   def withBackoff[In, Out, Mat](
       minBackoff: FiniteDuration,
       maxBackoff: FiniteDuration,
@@ -88,7 +86,6 @@ object RetryFlow {
    * @param flow a flow with context to retry elements from
    * @param decideRetry retry condition decision function
    */
-  @ApiMayChange(issue = "https://github.com/akka/akka/issues/27960";)
   def withBackoffAndContext[In, CtxIn, Out, CtxOut, Mat](
       minBackoff: FiniteDuration,
       maxBackoff: FiniteDuration,
diff --git 
a/stream/src/main/scala/org/apache/pekko/stream/snapshot/MaterializerState.scala
 
b/stream/src/main/scala/org/apache/pekko/stream/snapshot/MaterializerState.scala
index 92b354b831..ddbb8c8c3f 100644
--- 
a/stream/src/main/scala/org/apache/pekko/stream/snapshot/MaterializerState.scala
+++ 
b/stream/src/main/scala/org/apache/pekko/stream/snapshot/MaterializerState.scala
@@ -19,7 +19,7 @@ import scala.concurrent.duration._
 import org.apache.pekko
 import pekko.actor.{ ActorPath, ActorRef }
 import pekko.actor.ActorSystem
-import pekko.annotation.{ ApiMayChange, DoNotInherit, InternalApi }
+import pekko.annotation.{ DoNotInherit, InternalApi }
 import pekko.pattern.ask
 import pekko.stream.{ Attributes, Materializer }
 import pekko.stream.SystemMaterializer
@@ -40,7 +40,6 @@ object MaterializerState {
   /**
    * Dump stream snapshots of all streams of the default system materializer.
    */
-  @ApiMayChange
   def streamSnapshots(system: ActorSystem): Future[Seq[StreamSnapshot]] = {
     SystemMaterializer(system).materializer match {
       case impl: PhasedFusingActorMaterializer =>
@@ -52,7 +51,6 @@ object MaterializerState {
   /**
    * Dump stream snapshots of all streams of the given materializer.
    */
-  @ApiMayChange
   def streamSnapshots(mat: Materializer): Future[Seq[StreamSnapshot]] = {
     mat match {
       case impl: PhasedFusingActorMaterializer =>
@@ -88,7 +86,7 @@ object MaterializerState {
  *
  * Not for user extension
  */
-@DoNotInherit @ApiMayChange
+@DoNotInherit
 sealed trait StreamSnapshot {
 
   /**
@@ -108,7 +106,7 @@ sealed trait StreamSnapshot {
  *
  * Not for user extension
  */
-@DoNotInherit @ApiMayChange
+@DoNotInherit
 sealed trait InterpreterSnapshot {
   def logics: Seq[LogicSnapshot]
 }
@@ -118,13 +116,13 @@ sealed trait InterpreterSnapshot {
  *
  * Not for user extension
  */
-@DoNotInherit @ApiMayChange
+@DoNotInherit
 sealed trait UninitializedInterpreter extends InterpreterSnapshot
 
 /**
  * A stream interpreter that is running/has been started
  */
-@DoNotInherit @ApiMayChange
+@DoNotInherit
 sealed trait RunningInterpreter extends InterpreterSnapshot {
 
   /**
@@ -151,13 +149,12 @@ sealed trait RunningInterpreter extends 
InterpreterSnapshot {
 /**
  * Not for user extension
  */
-@DoNotInherit @ApiMayChange
+@DoNotInherit
 sealed trait LogicSnapshot {
   def label: String
   def attributes: Attributes
 }
 
-@ApiMayChange
 object ConnectionSnapshot {
 
   /** Not for user extension */
@@ -170,7 +167,7 @@ object ConnectionSnapshot {
 /**
  * Not for user extension
  */
-@DoNotInherit @ApiMayChange
+@DoNotInherit
 sealed trait ConnectionSnapshot {
   def in: LogicSnapshot
   def out: LogicSnapshot


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to