Skip to content

Non-spawning API for master and outstation creation #414

Description

@jadamcrain

Problem

The DNP3 library calls tokio::spawn internally in all spawn_* creation functions. This prevents callers from controlling which Tokio runtime or task set the futures are placed on.

Status

feature/no-spawn implements the master portion with unstable MasterBuilder / UdpMasterBuilder APIs. Associations are registered synchronously with add_association(...), which fails immediately on duplicate addresses and returns a scoped AssociationBuilder<'_> for adding polls. into_handle() releases the builder borrow, and the transport-specific into_* methods produce a MasterTask with async fn run(self).

The TCP outstation Server::into_task(listener) API synchronously consumes an already-bound listener and returns a ServerHandle plus an unpolled server task future. Existing stable bind_no_spawn() delegates to the same internal construction path.

The serial outstation API uses a fail-fast typestate flow: SerialOutstation::new(...) configures the protocol implementation synchronously, open(path, settings).await produces a SerialOutstationTask only after the port opens successfully, and run(self) permanently ends on shutdown or serial-port failure. The retrying spawn_outstation_serial_2() remains a separate stable API.

Remaining work

  • Outstation serial: fail-fast SerialOutstationopen()SerialOutstationTask::run() flow with no internal spawn or retry loop
  • Outstation TCP server: Server::into_task(listener) takes an already-bound listener synchronously and returns the server handle and task future
  • Gate the new master builder/task APIs behind an unstable feature
  • Document the semver exemption beside the unstable feature in Cargo.toml
  • Gate the new outstation task APIs behind unstable
  • Compile and test the unstable feature in CI
  • Ship in 1.7.0

unstable feature flag

Only the non-spawning APIs introduced as part of this 1.7.0 work go behind an unstable Cargo feature:

  • Exempt from semver: while items remain behind the flag, they may change or disappear in any release, including patch releases. This policy is documented beside the feature in Cargo.toml; the gated items are absent from the default published rustdoc.
  • No FFI schema entries and no guide pages for gated APIs.
  • Covers: MasterBuilder, UdpMasterBuilder, AssociationBuilder, MasterTask, Server::into_task, SerialOutstation, and SerialOutstationTask.
  • Existing stable APIs, including Server::bind_no_spawn and Server::add_outstation_no_spawn, are explicitly excluded and remain ungated.
  • General connection-handler conveniences such as the EndpointList::into_connect_handler* methods are separate stable API work and are not covered by this gate.

#276 concerns the existing stable no_spawn methods and is outside the scope of this issue.

Non-goals

  • FFI / language binding changes
  • Additional TLS-specific API work
  • Changes to existing public config types (semver)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions