Events

Event (ip.event)

An event is a single signed envelope carrying a JSON payload from one Odoo instance to another.

See also

Technical reference — sync_base.ip.event.

Fields

Field

Description

ip.event.direction

Either outbound (queued for delivery) or inbound (pending import).

ip.event.from_peer

The sender’s network node PeerID (multibase string).

ip.event.from_node_id

The sender’s network node (local gateway, foreign host).

ip.event.to_peer

The recipient’s network node PeerID (multibase string).

ip.event.to_node_id

The recipient’s network node (local gateway, foreign host).

ip.event.topic_id

The PubSub topic (ip.topic) this event belongs to.

ip.event.topic_name

Denormalized PubSub topic path string (e.g. /odoo/myswarm/v1/…).

See Namespace.

ip.event.seqno

Sequence number (UUID by default). Unique by origin (deduplication).

ip.event.signature

Standard Base64 encoded string (no padding). Created by the sender’s Ed25519 private key signing the raw UTF-8 payload.

ip.event.routing_mode

How the event is routed:
- Broadcast (all): multi-node broadcast to all peers in active swarms with at-most-once delivery.
- Direct (p2p): targeted point-to-point delivery to a specific recipient node.

broadcast or direct, configured on ip.topic.routing_mode.

ip.event.routing_state

Network lifecycle:
- Pending: in outbox, ready to send
- Sending: in transit, handed to gateway
- Sent: sent over network by gateway
- Failed: permanent delivery failure, not retried

See Routing State below for the full state machine.

ip.event.mapping_state

Mapping lifecycle:
- Ignored: not scheduled for mapping
- Waiting: waiting for CID to be fetched
- Pending: ready to be mapped
- Invalid: invalid json according to schema
- Failed: raised an error during mapping
- Mapped: successfully used

See Mapping State below for the full state machine.

ip.event.cid_ids

CIDs referenced by the payload.

See CIDs.

Routing State

Tracks delivery of an outbound event. Inspect at Sync ▸ Content ▸ Events.

pending ──► sending ──► sent
               └──────► failed

State

Meaning

pending

Queued, not yet picked up by the postman cron.

sending

Locked by the postman cron; delivery in progress.

sent

Successfully delivered to at least one peer.

failed

Delivery failed permanently after all retries.

Mapping State

Tracks import of an inbound event. Inspect at Sync ▸ Content ▸ Events.

(inbound) ──► ignored
          ──► pending ──► mapped
                     └──► failed
                     └──► invalid
                     └──► waiting ──► (CID pinned) ──► pending

State

Meaning

ignored

Received but not staged — ip.topic.auto_import off, no schema, or event did not match the topic’s ip.topic.import_domain.

pending

Queued for the mapping engine.

mapped

Successfully written to Odoo records.

waiting

A referenced CID is not yet pinned locally; unblocked automatically once the blob arrives.

failed

Schema mapping raised an exception; check ip.data.mapping_info.

invalid

Payload rejected by JSON Schema validation.

Export Flow (Odoo → Network)

  1. Selection: The automation or cron selects records matching the topic’s ip.topic.export_domain.

  2. Mapping: ip.schema._to_payload() translates each record into a validated JSON envelope. CID traits convert binary attachments to content addressing references and queue missing blobs for upload.

  3. Generation: One ip.event is created per record (or batch) with direction='outbound' and routing_state='pending'.

  4. Delivery: ip.swarm._dispatch_events() hands the events to the transport layer, which delivers to each non-gateway peer using that peer’s credentials.

Try Sending — action_run()

Groups the selected outbound events by topic and calls ip.topic._action_run_export_deliver(), bypassing the ip.topic.auto_deliver guard regardless of ip.topic.deliver_mode.

Target: events stuck in routing_state: pending or stalled in sending.

Import Flow (Network → Odoo)

The event lifecycle is standardized across all transport layers, governed by the mapping engine and the swarm dispatchers.

  1. Ingestion: Inbound events arrive via the REST controller (sync_http) or the gateway pull sweep (sync_kubo). The system performs immediate deduplication on the composite key (from_peer, seqno); duplicate payloads are discarded silently.

  2. Mapping: The mapping engine executes in three passes: a. Scan: Resolve lookups and identify relations. b. Search: Perform bulk ORM queries for upsert matching. c. Assemble: Execute create or write operations.

  3. CID-Wait: If an event references a CID that is not yet pinned locally, the is_cid trait raises MissingCidError and the event transitions to mapping_state: waiting. It remains blocked here until the CID fetcher resolves the blob, at which point the event is automatically re-queued for mapping.

Try Mapping — action_run()

Groups the selected inbound events by topic and calls ip.topic._action_run_import() on each group, bypassing the cron guard regardless of ip.topic.import_mode. Post-import server actions fire correctly. Events still blocked on an unresolved CID move back to waiting rather than failing again.

Target: events in mapping_state: failed or mapping_state: invalid.

See also

  • Topics — export, import, delivery, and delete configuration.

  • CIDs — CID state machine and the waiting unblock mechanism.

  • Odoo Schema — mapping engine, three-pass DataLoader, and is_cid trait.

  • Monitoring — infrastructure-level diagnostics.

  • sync_base.ip.event — technical reference.