Configuration¶
Topic (ip.topic)¶
A topic (ip.topic) is the primary configuration object.
It wires together:
the schema (
ip.schema) defining the bidirectional JSON ↔ Odoo mapping,the export triggers (instant automation or scheduled cron),
the import cadence (instant or batch cron),
the delivery mode (push or pull) and retry count,
a garbage-collection domain (
ip.topic.delete_domain) for pruning old events.
Topics auto-create and self-heal their base.automation and ir.cron records; manual activation of a managed cron is blocked to prevent conflicts.
Note
A topic on a staging or development database is automatically neutralized: its outbound automations are disabled so test data cannot reach production peers. Re-enable them explicitly before using the database as a live node.
See also
Technical references — sync_base.ip.topic, sync_kubo.ip.topic.
Auto-managed Infrastructure¶
When you save a topic, ip.topic._sync_infra() creates or updates:
a
base.automation(forexport_mode = instant), andone or more
ir.cronrecords (for batch export, batch import, delivery, and GC).
These records are self-healing: if you delete or disable one, the topic recreates it on the next save.
Warning
Manually disabling a topic-managed cron is not persistent — base.automation.write() and ir.cron.write() both enforce an activation guard that raises a UserError if you try to re-enable a managed record directly.
To pause all activity on a topic, use the topic’s Active toggle or archive the record.
Export¶
On each export run the automation or cron selects records matching ip.topic.export_domain, passes them through ip.schema._to_payload(), and creates one ip.event per record (or per batch when ip.topic.event_array_size > 1) with direction='outbound' and routing_state='pending'.
Field |
Effect |
|---|---|
Instant: Creates an event instantly when a record is saved.
Batch: A cron job sweeps records periodically to generate events.
Use |
|
Defines which Odoo records are candidates for auto-export.
- Batch: The export cron sweeps records matching this domain.
- Instant: The automation synchronously triggers for records matching this domain.
Once an event is created, this domain won’t restrict it from being sent.
Leave empty to export every record of the target model. |
|
Maximum number of outbound ip.event payloads to generate per export run (0 = no limit).
If payload type is ‘Array’, the export will sweep (Batch Size x Array Size) Odoo records per run.
|
|
Maximum number of Odoo records per ip.event of type ‘array’.
See Data Schema for |
|
Server action bound to the model’s Action menu for manual record-level export.
|
Hook — ip.topic.export_server_action_id runs after events are generated, with the exported records as active_ids in context.
Use it to stamp a synced flag or trigger downstream logic.
To prevent an infinite export cycle, export crons are not re-triggered if the exported records still match the export_domain after running that action.
To trigger a sync export from any server action, set its state to sync_send — this invokes ir.actions.server._run_action_sync_send().
Tip
Never point export_server_action_id at another sync_send action — the topic detects the loop and raises a ValidationError.
Note
On a database with no live gateway node (staging, dev), outbound automations are disabled automatically.
Re-enable the automation or re-set export_mode to trigger ip.topic._sync_infra() before going live.
Export & Send — action_run_export_deliver()
Generates events from records matching ip.topic.export_domain then immediately dispatches them in one step.
Bypasses auto_export, ip.topic.auto_deliver, and pull-mode restrictions.
The most common manual trigger.
Export (batch mode) — action_run_export()
Visible only when export_mode = batch.
Generates events and parks them in routing_state: pending without pushing to the network.
Use to stage events before delivery.
Import¶
On each import run the engine calls ip.event._try_mapping() on pending inbound events, running the schema AST in three passes: scan lookups, bulk ORM search, then assemble and execute create/write calls.
Field |
Effect |
|---|---|
Instant: Maps inbound events immediately in ip.event.create() when domains match.
Batch: Events are parked as pending and mapped by the import cron.
Use |
|
Maximum number of events to ingest per cron execution (0 = no limit).
|
|
Automatically map inbound events to records.
When |
Hook — ip.topic.import_server_action_id fires after the schema engine successfully maps inbound events to Odoo records, with the created or updated records as active_ids in context.
Use it to send emails, update related models, or trigger other downstream business logic.
Import — action_run_import()
Sweeps pending inbound events for this topic and maps them into Odoo records, up to ip.topic.import_batch_size.
Bypasses cron guards and does not re-trigger the import cron.
Delivery¶
The postman ir.cron polls for events with routing_state = pending and dispatches them via ip.swarm._dispatch_events().
With ip.topic.deliver_mode = push the gateway POSTs to each peer directly; with pull peers call /v0/pull on their own schedule.
Field |
Effect |
|---|---|
Determines how pending events reach the Gateway.
PUSH: Odoo actively sends events to the Gateway.
- Auto-Deliver ON: Dispatched instantly. Failures are retried by the Global Postman.
- Auto-Deliver OFF: Requires manual dispatch. Failures are NOT retried.
PULL: The Gateway continuously polls Odoo for events.
- Auto-Deliver ON: The Gateway is permitted to fetch pending events.
- Auto-Deliver OFF: The Gateway is blocked. You must manually force a push.
Use |
|
How the topic routes events:
- Broadcast (all): multi-node broadcast to all peers in active swarms with at-most-once delivery.
- Direct (p2p): targeted point-to-point delivery to specific nodes resolved by __nodes__ in payload.
Use direct (see |
|
Maximum number of events to dispatch per cron run (0 = no limit). Actual batch may be smaller when concurrent deliveries lock events for sending.
|
|
If disabled, events are only sent once.
- Push: The Global Postman will not attempt to resend if the Gateway is offline.
- Pull: Odoo will not re-serve the events if the Gateway crashes before confirming them.
Ideal for high-volume transient data.
When |
|
If enabled, events generated by this topic are automatically queued for delivery. If disabled, events remain ‘pending’ until you manually click ‘Run Delivery’ (push).
|
Run Postman — action_run_deliver()
Sweeps all pending or stalled outbound events in this topic’s outbox and pushes them to the gateway.
Bypasses the pull-mode restriction so admins can force-push events that are normally polled.
Does not re-trigger the global postman cron.
Delete¶
A GC ir.cron runs periodically when ip.topic.auto_delete = True, applying ip.topic.delete_domain to prune old ip.event records and keep table growth bounded.
Field |
Effect |
|---|---|
Automatically delete old events in this topic matching a specific domain.
|
|
Events in this topic matching this domain will be unlinked by the Garbage Collection cron.
Context variables: datetime, timedelta, relativedelta, context_today, env.
The default retains events for 7 days and only prunes fully delivered or mapped ones (see below). |
Default delete_domain:
[
('write_date', '<', context_today() - relativedelta(days=7)),
'|', '|',
'&', ('direction', '=', 'inbound'), ('mapping_state', '=', 'mapped'),
'&', ('direction', '=', 'inbound'), '&', ('mapping_state', '=', 'ignored'), ('mapping_info', '=', False),
'&', ('direction', '=', 'outbound'), ('routing_state', '=', 'sent')
]
The 7-day window gives offline peers time to catch up and leaves a debugging window.
Override ip.topic.delete_domain to retain specific events for audit purposes rather than disabling ip.topic.auto_delete entirely.
Run Collector — action_run_delete()
Immediately evaluates ip.topic.delete_domain against this topic’s events and permanently unlinks matching records.
Does not re-trigger the global collector cron.