Class PushEngine

java.lang.Object
com.iizix.server.push.engine.PushEngine
All Implemented Interfaces:
IPushNotificationEngine

public final class PushEngine extends Object implements IPushNotificationEngine
The push notification engine: the runtime that owns the executor, the concurrency ceiling, the store, the spool, the transports and the resolver, and performs sends.

Concurrency. Sends run on a virtual-thread-per-task executor, unbounded by construction; the hard ceiling on notifications in flight is a Semaphore sized to IPushSettings.getMaxParallelPush(), acquired before every dispatch and released on completion. The setting is read once at start and held.

A send builds its RoutingPlan first (the audit record, the authorization check and the area filter all happen there, before anything leaves), then dispatches every target of every slice under a permit, records one outcome per target and completes the future with the PushResultImpl. A device target goes to its transport; an in-session target to the IInSessionDelivery seam, with the ruled fallback: when the app session closed holding the notification, a device push from this same server.

Failures become spool entries. A transient transport failure spools the notification for that target with exponential backoff; a replay loop on its own virtual thread sends due entries, re-resolving each subscription so a re-registered device is reached at its new endpoint, and persists the spool after each pass and at shutdown.

Single server. Every slice is local; the region tree names regions for the audit record and the area filter and never routes remotely. Nothing changes in the interfaces when that arrives.

Author:
Christopher Mindus
  • Constructor Details

    • PushEngine

      public PushEngine(PushEngine.Config cfg)
      Constructor. Nothing runs until start().
      Parameters:
      cfg - The collaborators; settings, store, users, configs and spool are required.
  • Method Details

    • start

      public void start() throws SQLException
      Starts the engine: creates the ceiling and the executor, ensures the schema, loads the spool and starts the replay loop.
      Throws:
      IllegalStateException - If the engine is not in PushEngineState.NOT_STARTED.
      SQLException - If the subscription table cannot be created or migrated.
    • getState

      public PushEngineState getState()
      Description copied from interface: IPushNotificationEngine
      Gets the current lifecycle state of the engine.
      Specified by:
      getState in interface IPushNotificationEngine
      Returns:
      The state; never null.
    • isDisposed

      public boolean isDisposed()
      Description copied from interface: IPushNotificationEngine
      Reports whether the engine has been disposed.

      A disposed engine is in PushEngineState.STOPPED and performs no further work; the next access to the service creates a fresh engine rather than reviving this one.

      Specified by:
      isDisposed in interface IPushNotificationEngine
      Returns:
      true if this engine has been disposed.
    • dispose

      public void dispose()
      Description copied from interface: IPushNotificationEngine
      Disposes the engine: transitions through PushEngineState.STOPPING to PushEngineState.STOPPED, refusing new sends, allowing in-flight sends to complete, persisting the spool, and releasing the executor and transports. Idempotent — disposing an already-disposed engine has no effect.
      Specified by:
      dispose in interface IPushNotificationEngine
    • getSettings

      public IPushSettings getSettings()
      --- Accessors ---
      Specified by:
      getSettings in interface IPushNotificationEngine
      Returns:
      The settings; never null.
    • getRegionTree

      public IRegionTree getRegionTree()
      Description copied from interface: IPushNotificationEngine
      Gets the region tree the router resolves residency against.
      Specified by:
      getRegionTree in interface IPushNotificationEngine
      Returns:
      The region tree; never null.
    • newMessageBuilder

      public IPushNotificationMessageBuilder newMessageBuilder()
      Description copied from interface: IPushNotificationEngine
      Creates a new, empty message builder bound to this engine, so that defaults such as TTL are taken from this engine's settings.
      Specified by:
      newMessageBuilder in interface IPushNotificationEngine
      Returns:
      A fresh IPushNotificationMessageBuilder; never null.
    • getStore

      public SubscriptionStore getStore()
      Gets the store.
      Returns:
      The subscription store.
    • getUsers

      public UserDirectory getUsers()
      Gets the user directory.
      Returns:
      The directory.
    • getConfigs

      public AppPushConfigs getConfigs()
      Gets the application configurations.
      Returns:
      The configurations.
    • getResolver

      public PushResolver getResolver()
      Gets the resolver.
      Returns:
      The resolver.
    • getSpool

      public PushSpool getSpool()
      Gets the spool.
      Returns:
      The spool.
    • getTransport

      public IPushTransport getTransport(PushTransport kind)
      Gets a transport.
      Parameters:
      kind - The kind.
      Returns:
      The transport, or null when the engine has none of that kind.
    • getMaxParallel

      public int getMaxParallel()
      Gets the ceiling the engine started with.
      Returns:
      The maximum in flight.
    • getInFlight

      public int getInFlight()
      Gets the number of sends in flight now.
      Returns:
      The in-flight count.
    • planSend

      public IRoutingPlan planSend(IPushSendRequest request) throws PushAuthorizationException
      --- Planning and sending ---
      Specified by:
      planSend in interface IPushNotificationEngine
      Parameters:
      request - The send request (filter, notification, policies, authorization context).
      Returns:
      The routing plan that a real send of this request would follow.
      Throws:
      PushAuthorizationException - if the request's operator is not authorized for a region the plan requires.
    • send

      Description copied from interface: IPushNotificationEngine
      Performs a send asynchronously.

      Builds the routing plan, checks authorization, then dispatches each region slice — local slices through this server's send path, remote slices to the region's server over the server-to-server channel — acquiring a concurrency permit per dispatch so the in-flight count never exceeds IPushSettings.getMaxParallelPush(). Unreachable regions and unreachable endpoints spool. The returned future completes when every slice has been resolved, with a PushResult that carries the routing plan and the per-target, per-region, per-tier outcomes.

      To wait a bounded time for completion, call future.get(timeout, unit) on the result — the framework's completion handle is a standard CompletableFuture.

      Specified by:
      send in interface IPushNotificationEngine
      Parameters:
      request - The send request.
      progress - An optional progress callback invoked as slices complete, for bulk sends; may be null.
      Returns:
      A future completing with the aggregate PushResult.
    • sendToUsers

      public PushResultImpl sendToUsers(String appId, String topic, long[] uids, IPushNotification message) throws Exception
      Sends a notification to users by ID for an application and Topic, with the server's default policies and an unrestricted operator, and waits a bounded time.
      Parameters:
      appId - The application ID, * for every application.
      topic - The Topic, empty for every Topic.
      uids - The user IDs.
      message - The notification.
      Returns:
      The result.
      Throws:
      Exception - If the send fails or times out.
    • spoolFile

      public static File spoolFile(IPushSettings settings, File serverDir)
      Gets the default spool file of a server: <spoolDirectory>/pnspool.xml, the spool directory being the setting when non-empty, else push-spool under the server's current directory.
      Parameters:
      settings - The settings.
      serverDir - The server's current directory.
      Returns:
      The file.