Postboy Help

Executor

Purpose

Executor in Postboy is a synchronous execution contract.

Unlike Message and CallbackMessage, which are processed through RxJS-based flows, an executor is used when you need to execute a function immediately and get the result synchronously.

This is the abstraction Postboy uses for command-like operations that do not need an asynchronous stream.

Why executors exist

In many applications, there are operations that:

  • do not need async processing

  • do not belong to an event stream

  • should return a value right away

  • should be testable as ordinary functions

  • should not be implemented as static helpers or global utility functions

Executors solve this by making the operation a first-class object inside the Postboy architecture.

That gives you synchronous execution without falling back to static methods or tightly coupled utility code.

How Executors differ from Message and CallbackMessage

Message

Message is used for asynchronous silent communication.

publisher → subscription → handling

It is a good fit for events and commands that do not need a result.

CallbackMessage

CallbackMessage is used for asynchronous flows that expect a result.

sender → callback flow → result observable

It is a good fit for request/response style interaction that still belongs to the reactive pipeline.

Executor

Executor is used for synchronous execution.

caller → exec(...) → result

It is a good fit for operations that should return immediately.

Typical use cases

Executors are useful for operations such as:

  • date formatting

  • cache cleanup

  • value transformation

  • local validation

  • building derived data

  • lightweight synchronous commands

If the operation is not inherently async, making it a message or callback flow is usually unnecessary.

Why this helps architecture

Executors help keep the codebase clean by moving synchronous operations out of:

  • static functions

  • global utility modules

  • ad hoc helper classes

  • tightly coupled service methods

Instead, the operation becomes a typed object with a clear contract and a predictable execution path.

That improves:

  • dependency injection friendliness

  • testability

  • composability

  • architectural consistency

Contract example

class FormatDateExecutor extends PostboyExecutor<string> { static ID = 'date.format'; constructor(public readonly date: Date) { super(); } }

This executor says:

  • it represents a synchronous operation

  • it accepts a Date

  • it returns a string

Execution example

const formatted = postboy.exec(new FormatDateExecutor(new Date()));

The caller gets the result immediately.

There is no observable stream, no callback completion flow, and no waiting for a subscriber to respond.

When to use executor vs message/subscription

Use Executor when:

  • the operation is synchronous

  • the result is needed immediately

  • the logic is local and direct

  • you want to avoid static utility code

  • the operation belongs to application logic or infrastructure logic that does not need RxJS

Use Message when:

  • the operation is event-driven

  • multiple listeners may react

  • the result is not needed immediately

  • the flow should stay reactive

Use CallbackMessage when:

  • the caller needs a result

  • the flow should still be reactive

  • the response is part of the message pipeline

Why not just use static functions

Static helpers are convenient, but they often weaken architecture:

  • they are harder to inject

  • they are harder to replace in tests

  • they hide dependencies

  • they make the code harder to compose cleanly

Executors provide the same directness, but with a typed object model that fits better into DI-based applications.

Summary

Executor is Postboy’s synchronous execution model.

It is used for operations that should run immediately, return a result directly, and stay cleanly integrated with the architecture without relying on static helpers or asynchronous message flows.

04 мая 2026