From dbd90e6eb19142c9a8796560b443834e8532136c Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Thu, 5 Mar 2026 14:53:32 -0500 Subject: [PATCH] changing the reporting visibility of the event bus broadcast channel and removing the need to maintain an 'original channel' --- .../avatar/support/CorpseRemovalActor.scala | 2 +- .../avatar/support/DroppedItemRemover.scala | 4 ++-- .../services/base/GenericEventService.scala | 11 ++++++----- ...nericEventServiceWithCacheAndSupport.scala | 2 +- .../services/base/bus/GenericEventBus.scala | 19 ++++++++++--------- .../services/base/envelope/AllEnvelopes.scala | 4 ++-- .../envelope/GenericMessageEnvelope.scala | 4 +--- .../envelope/GenericResponseEnvelope.scala | 2 ++ .../base/envelope/MessageEnvelope.scala | 11 ++++------- .../services/galaxy/GalaxyService.scala | 2 +- .../local/support/DoorCloseActor.scala | 2 +- .../local/support/HackClearActor.scala | 2 +- .../scala/objects/FacilityTurretTest.scala | 1 - src/test/scala/objects/RepairableTest.scala | 1 - .../scala/objects/VehicleControlTest.scala | 2 +- .../objects/terminal/ProximityTest.scala | 1 - .../scala/service/base/EnvelopeTest.scala | 6 +++--- .../base/EventServiceCacheSupportTest.scala | 2 +- .../scala/service/base/EventServiceTest.scala | 12 ++++++------ .../service/base/EventServiceTestBase.scala | 2 +- 20 files changed, 44 insertions(+), 48 deletions(-) diff --git a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala index 7a1f16e00..4f86597e8 100644 --- a/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala +++ b/src/main/scala/net/psforever/services/avatar/support/CorpseRemovalActor.scala @@ -13,7 +13,7 @@ import net.psforever.services.base.message.ObjectDelete import scala.concurrent.duration._ final case class ReleaseEnvelope( - originalChannel: String, + channel: String, filter: PlanetSideGUID, msg: Release ) diff --git a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala index 8224c53af..bb74a68e6 100644 --- a/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala +++ b/src/main/scala/net/psforever/services/avatar/support/DroppedItemRemover.scala @@ -14,7 +14,7 @@ import net.psforever.types.PlanetSideGUID import scala.concurrent.duration._ final case class PickupItemEnvelope( - originalChannel: String, + channel: String, filter: PlanetSideGUID, msg: PickupItem, zone: Zone @@ -33,7 +33,7 @@ object PickupItemEnvelope { } final case class DropItemEnvelope( - originalChannel: String, + channel: String, filter: PlanetSideGUID, msg: DropItem, zone: Zone diff --git a/src/main/scala/net/psforever/services/base/GenericEventService.scala b/src/main/scala/net/psforever/services/base/GenericEventService.scala index a9dee3312..183daf018 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventService.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventService.scala @@ -18,11 +18,12 @@ import org.log4s.Logger */ trait EventSystemStamp { /* - Example Classifiers: "foo", "foo.fizz", and "foo.buzz" - In general, Classifier channels will perform left-pattern matching. - "foo" will publish to "foo", "foo.fizz", and "foo.buzz" - To isolate "foo", one must distinguish it with a right-pattern. - "foo" is appended as "foo.bar" and no longer publishes to "foo.fizz.bar" or to "foo.buzz.bar" + Example: + The channels are "foo", "foo.fizz", and "foo.buzz" + In general, Classifier channels will perform left-pattern matching + Publishing to channel "foo" will allocate Classifiers "foo", "foo.fizz", and "foo.buzz" + To isolate "foo", one must distinguish it with a right-pattern such as "out" + Publishing to channel "foo.out" no longer publishes to "foo.fizz.out" or to "foo.buzz.out" */ /** * Take an input channel and produce the publishing output channel. diff --git a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala index 665d90b6e..ee5a283ac 100644 --- a/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala +++ b/src/main/scala/net/psforever/services/base/GenericEventServiceWithCacheAndSupport.scala @@ -31,7 +31,7 @@ trait CachedGenericEventEnvelope final case class CachedEnvelope( guid: PlanetSideGUID, - originalChannel: String, + channel: String, filter: PlanetSideGUID, msg: EventMessage ) extends CachedGenericEventEnvelope { diff --git a/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala b/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala index b130d8eff..57454399d 100644 --- a/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala +++ b/src/main/scala/net/psforever/services/base/bus/GenericEventBus.scala @@ -20,19 +20,20 @@ class GenericEventBus type Event = GenericResponseEnvelope type Classifier = String - protected def classify(event: Event): Classifier = event.channel + protected def classify(event: Event): Classifier = event.outChannel /* - Example Classifiers: "foo", "foo.fizz", and "foo.buzz" - In general, Classifier channels will perform left-pattern matching. - "foo" will publish to "foo", "foo.fizz", and "foo.buzz" + Example: + The channels are "foo", "foo.fizz", and "foo.buzz" + In general, Classifier channels will perform left-pattern matching + Publishing to channel "foo" will allocate Classifiers "foo", "foo.fizz", and "foo.buzz" + See `GenericResponseEnvelope.outChannel` to determine how this is applied */ - protected def subclassification: Subclassification[String] = - new Subclassification[Classifier] { - def isEqual(x: Classifier, y: Classifier): Boolean = x == y + protected def subclassification: Subclassification[String] = new Subclassification[Classifier] { + def isEqual(x: Classifier, y: Classifier): Boolean = x.equals(y) - def isSubclass(x: Classifier, y: Classifier): Boolean = x.startsWith(y) - } + def isSubclass(x: Classifier, y: Classifier): Boolean = x.startsWith(y) + } override def publish(event: Event): Unit = { super[SubchannelClassification].publish(event) diff --git a/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala b/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala index aa737c55d..7e067d5d5 100644 --- a/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala +++ b/src/main/scala/net/psforever/services/base/envelope/AllEnvelopes.scala @@ -8,8 +8,8 @@ import net.psforever.types.PlanetSideGUID * Defines a channel and a filter, both of which server the purpose of routing the message to its destination. */ trait AllEnvelopes { - /** set of subscribers on an event system bus the envelope should reach */ + /** set of subscribers on an event system bus that the envelope should reach */ def channel: String - /** specific subscriber endpoint to be excluded (the subscriber should filter themselves) */ + /** specific subscriber endpoint to be excluded (the subscriber should filter themselves upon receipt) */ def filter: PlanetSideGUID } diff --git a/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala index d792ce4ec..eaa62e792 100644 --- a/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala +++ b/src/main/scala/net/psforever/services/base/envelope/GenericMessageEnvelope.scala @@ -7,8 +7,6 @@ import net.psforever.types.PlanetSideGUID trait GenericMessageEnvelope extends AllEnvelopes { - /** channel information provided with the message */ - def originalChannel: String /** input payload transported by this envelope */ def msg: EventMessage /** method that counts as "processing" the envelope by an event system; @@ -25,6 +23,6 @@ object GenericMessageEnvelope { * @return a tuple containing the channel, filter, and reply message */ def unapply(obj: GenericMessageEnvelope): Option[(String, PlanetSideGUID, EventMessage)] = { - Some((obj.originalChannel, obj.filter, obj.msg)) + Some((obj.channel, obj.filter, obj.msg)) } } diff --git a/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala index 5b77aeca6..001513b10 100644 --- a/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala +++ b/src/main/scala/net/psforever/services/base/envelope/GenericResponseEnvelope.scala @@ -14,6 +14,8 @@ trait GenericResponseEnvelope def reply: EventResponse /** marker indicating the routing through which the original message was processed */ def stamp: EventSystemStamp + /** channel information tailored to the event system */ + def outChannel: String = stamp.routing(channel) } object GenericResponseEnvelope { diff --git a/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala b/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala index db555c944..9ab7f8a09 100644 --- a/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala +++ b/src/main/scala/net/psforever/services/base/envelope/MessageEnvelope.scala @@ -14,7 +14,9 @@ case object NoReply extends EventResponse * A stamp that represents not having been processed by an event system. * Should never been given out to an event system. */ -case object Undelivered extends EventSystemStamp +case object Undelivered extends EventSystemStamp { + override def routing(channel: String): String = "" +} /** * The mechanics of a proper event system envelope. @@ -32,16 +34,11 @@ trait MessageTransformationBehavior extends GenericMessageEnvelope with GenericResponseEnvelope { private var outputStamp: EventSystemStamp = Undelivered - private var outputChannel: String = originalChannel private var outputReply: EventResponse = NoReply - // satisfies GenericMessageEnvelope (and GenericResponseEnvelope) - def channel: String = outputChannel - // satisfies GenericMessageEnvelope def response(stamp: EventSystemStamp): GenericResponseEnvelope = { outputStamp = stamp - outputChannel = stamp.routing(originalChannel) outputReply = msg.response() this } @@ -54,5 +51,5 @@ trait MessageTransformationBehavior /** * A proper event system envelope. */ -case class MessageEnvelope(originalChannel: String, filter: PlanetSideGUID, msg: EventMessage) +case class MessageEnvelope(channel: String, filter: PlanetSideGUID, msg: EventMessage) extends MessageTransformationBehavior diff --git a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala index b3d4c084e..79569a4e0 100644 --- a/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala +++ b/src/main/scala/net/psforever/services/galaxy/GalaxyService.scala @@ -9,7 +9,7 @@ case object GalaxyStamp extends EventSystemStamp { if (channel.trim.isEmpty) { "/out" } else { - s"/$channel/out" + super.routing(channel) } } } diff --git a/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala b/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala index a8ad7e9ae..67387b6f7 100644 --- a/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala +++ b/src/main/scala/net/psforever/services/local/support/DoorCloseActor.scala @@ -15,7 +15,7 @@ import scala.annotation.tailrec import scala.concurrent.duration._ final case class DoorMessage( - originalChannel: String, + channel: String, msg: IsADoorMessage, supportMessage: Any ) extends GenericSupportEnvelope { diff --git a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala index 5f6d964f6..92b02dec2 100644 --- a/src/main/scala/net/psforever/services/local/support/HackClearActor.scala +++ b/src/main/scala/net/psforever/services/local/support/HackClearActor.scala @@ -18,7 +18,7 @@ import scala.annotation.tailrec import scala.concurrent.duration._ final case class HackEntityEnvelope( - originalChannel: String, + channel: String, filter: PlanetSideGUID, msg: IsAHackMessage, supportMessage: Any diff --git a/src/test/scala/objects/FacilityTurretTest.scala b/src/test/scala/objects/FacilityTurretTest.scala index bba0f9570..105652f08 100644 --- a/src/test/scala/objects/FacilityTurretTest.scala +++ b/src/test/scala/objects/FacilityTurretTest.scala @@ -19,7 +19,6 @@ import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.packet.game.{InventoryStateMessage, RepairMessage} import net.psforever.types._ import org.specs2.mutable.Specification -import net.psforever.services.avatar.AvatarAction import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import net.psforever.services.vehicle.VehicleAction diff --git a/src/test/scala/objects/RepairableTest.scala b/src/test/scala/objects/RepairableTest.scala index a558b6487..20d49812f 100644 --- a/src/test/scala/objects/RepairableTest.scala +++ b/src/test/scala/objects/RepairableTest.scala @@ -17,7 +17,6 @@ import net.psforever.objects.vehicles.control.VehicleControl import net.psforever.objects.zones.{Zone, ZoneMap} import net.psforever.packet.game.{InventoryStateMessage, RepairMessage} import net.psforever.types._ -import net.psforever.services.avatar.AvatarAction import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} import net.psforever.services.vehicle.VehicleAction diff --git a/src/test/scala/objects/VehicleControlTest.scala b/src/test/scala/objects/VehicleControlTest.scala index 54306b8ae..e57ed428f 100644 --- a/src/test/scala/objects/VehicleControlTest.scala +++ b/src/test/scala/objects/VehicleControlTest.scala @@ -27,7 +27,7 @@ import net.psforever.packet.game._ import net.psforever.services.ServiceManager import net.psforever.services.base.envelope.MessageEnvelope import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse} -import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} +import net.psforever.services.vehicle.VehicleAction import net.psforever.types._ import scala.concurrent.duration._ diff --git a/src/test/scala/objects/terminal/ProximityTest.scala b/src/test/scala/objects/terminal/ProximityTest.scala index 25b347acc..2d6334774 100644 --- a/src/test/scala/objects/terminal/ProximityTest.scala +++ b/src/test/scala/objects/terminal/ProximityTest.scala @@ -14,7 +14,6 @@ import net.psforever.objects.{GlobalDefinitions, Player} import net.psforever.types.{CharacterSex, CharacterVoice, PlanetSideEmpire, PlanetSideGUID} import org.specs2.mutable.Specification import net.psforever.services.Service -import net.psforever.services.local.LocalService import scala.concurrent.duration._ import akka.actor.typed.scaladsl.adapter._ diff --git a/src/test/scala/service/base/EnvelopeTest.scala b/src/test/scala/service/base/EnvelopeTest.scala index 4c760a117..b2f11c1f5 100644 --- a/src/test/scala/service/base/EnvelopeTest.scala +++ b/src/test/scala/service/base/EnvelopeTest.scala @@ -56,7 +56,7 @@ class EnvelopeTest extends Specification { val input = MessageEnvelope("test", TestFilter, TestMessage(5)) val output = input.response(TestStamp) output match { - case reply @ GenericResponseEnvelope("/test/out", TestFilter, TestMessage(5)) => + case reply @ GenericResponseEnvelope("test", TestFilter, TestMessage(5)) => reply.stamp mustEqual TestStamp case _ => ko @@ -67,7 +67,7 @@ class EnvelopeTest extends Specification { val input = MessageEnvelope("test", TestFilter, TestInputMessage(5)) val output = input.response(TestStamp) output match { - case reply @ GenericResponseEnvelope("/test/out", TestFilter, TestOutputEvent(7)) => + case reply @ GenericResponseEnvelope("test", TestFilter, TestOutputEvent(7)) => reply.stamp mustEqual TestStamp case _ => ko @@ -79,7 +79,7 @@ class EnvelopeTest extends Specification { "construct (quick)" in { val input = GenericResponseEnvelope(TestStamp, "test", TestFilter, TestMessage(5)) input match { - case reply @ GenericResponseEnvelope("/test/out", TestFilter, TestMessage(5)) => + case reply @ GenericResponseEnvelope("test", TestFilter, TestMessage(5)) => reply.stamp mustEqual TestStamp case _ => ko diff --git a/src/test/scala/service/base/EventServiceCacheSupportTest.scala b/src/test/scala/service/base/EventServiceCacheSupportTest.scala index ad42c35e1..6ff7932f5 100644 --- a/src/test/scala/service/base/EventServiceCacheSupportTest.scala +++ b/src/test/scala/service/base/EventServiceCacheSupportTest.scala @@ -14,7 +14,7 @@ import scala.concurrent.duration._ object EventServiceCacheSupportTest { final case class CachedSupportTestEnvelope( guid: PlanetSideGUID, - originalChannel: String, + channel: String, override val msg: EventMessage, supportMessage: Any ) extends CachedGenericEventEnvelope with GenericSupportEnvelope { diff --git a/src/test/scala/service/base/EventServiceTest.scala b/src/test/scala/service/base/EventServiceTest.scala index 0bde5e87f..8bfbf61dd 100644 --- a/src/test/scala/service/base/EventServiceTest.scala +++ b/src/test/scala/service/base/EventServiceTest.scala @@ -92,7 +92,7 @@ class EventServiceTestNotSubscribed extends ActorTest { events ! MessageEnvelope("test", Service.defaultPlayerGUID, TestMessage(5)) val reply = probe.receiveOne(100 milliseconds) reply match { - case GenericResponseEnvelope("/test/out", _, TestMessage(5)) => () + case GenericResponseEnvelope("test", _, TestMessage(5)) => () case _ => assert(false, "(2) message expected but not received") } missedProbe.expectNoMessage(100 milliseconds) @@ -127,11 +127,11 @@ class EventServiceTestLeave extends ActorTest { events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(5)) val reply1 = probe.receiveN(2, 100 milliseconds) reply1.head match { - case GenericResponseEnvelope("/test/out", _, _) => () + case GenericResponseEnvelope("test", _, _) => () case _ => assert(false, "(3) message expected but not received") } reply1(1) match { - case GenericResponseEnvelope("/anotherTest/out", _, _) => () + case GenericResponseEnvelope("anotherTest", _, _) => () case _ => assert(false, "(4) message expected but not received") } @@ -140,7 +140,7 @@ class EventServiceTestLeave extends ActorTest { events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) val reply2 = probe.receiveOne(100 milliseconds) reply2 match { - case GenericResponseEnvelope("/test/out", _, TestMessage(5)) => () + case GenericResponseEnvelope("test", _, TestMessage(5)) => () case _ => assert(false, "(5) message expected but not received") } probe.expectNoMessage(250 milliseconds) @@ -161,11 +161,11 @@ class EventServiceTestLeaveAll extends ActorTest { events ! MessageEnvelope("anotherTest", Service.defaultPlayerGUID, TestMessage(6)) val reply = probe.receiveN(2,100 milliseconds) reply.head match { - case GenericResponseEnvelope("/test/out", _, TestMessage(5)) => () + case GenericResponseEnvelope("test", _, TestMessage(5)) => () case _ => assert(false, "(6) message expected but not received") } reply(1) match { - case GenericResponseEnvelope("/anotherTest/out", _, TestMessage(6)) => () + case GenericResponseEnvelope("anotherTest", _, TestMessage(6)) => () case _ => assert(false, "(7) message expected but not received") } diff --git a/src/test/scala/service/base/EventServiceTestBase.scala b/src/test/scala/service/base/EventServiceTestBase.scala index f5ac013d7..40718e204 100644 --- a/src/test/scala/service/base/EventServiceTestBase.scala +++ b/src/test/scala/service/base/EventServiceTestBase.scala @@ -29,7 +29,7 @@ object EventServiceTestBase { } final case class TestSupportEnvelope( - originalChannel: String, + channel: String, msg: SupportActorRepliesWith ) extends GenericSupportEnvelope { def filter: PlanetSideGUID = Service.defaultPlayerGUID