# Messaging (ActiveMQ / RocketMQ) Not every integration in xly is a synchronous HTTP call. The framework runs two message brokers, each with a different role: | Broker | Used for | Producer | Consumer | |---|---|---|---| | **ActiveMQ / JMS** | In-cluster fan-out events: base-data merge jobs (consolidating per-tenant rows into flattened lookup tables) and document-update / document-delete notifications. **Despite the historical naming of one queue, this channel is NOT used for Redis cache invalidation** — see [Cache invalidation on metadata change](../reference/maintainer/cache-invalidation.md) for the actual cache-evict path. | `xlyErpJmsProductor` | `xlyErpJmsConsumer` | | **RocketMQ** | Other integration flows where the ActiveMQ assumptions don't fit. | `RocketMQServiceImpl` (in `xlyBusinessService`) | (varies — service-specific) | This page is a pointer rather than a deep dive — exact queue names and payloads are documented at the consumer-thread level in `xlyErpJmsConsumer/src/main/java/com/xly/xlyerpjmsconsumer/`. ## ActiveMQ / JMS — base-data merge + fan-out channel Producer-side queue declarations live in `xlyErpJmsProductor/src/main/java/com/xly/xlyerpjmsproductor/config/P2pQueue.java`. The full set is **24 destinations**, grouped by intent: ### Module / control (2) | Constant | Purpose | |---|---| | `ERP_JMS_ACTIVEMQ_CHANGE_GDS_MODULE` | "Module metadata changed" — `ConsumerChangeGdsModuleThread` runs the stored proc `PRO_ERPMERGEBASEGDSMODULE` to merge per-tenant `gdsmodule` rows into a flattened base lookup table. **Does not invalidate Redis caches** despite the name — Redis cache eviction happens synchronously via `@CacheEvict` in BACK during save. See [Cache invalidation on metadata change](../reference/maintainer/cache-invalidation.md). | | `ERP_JMS_ACTIVEMQ_CHANGE_WORK_ORDER_CONTROL` | Work-order control state changed (status/aggregate flags) — fan-out for downstream recalculation. | ### Document operations (6) | Constant | Purpose | |---|---| | `ERP_JMS_ACTIVEMQ_UPD_SALE_ORDER` / `_UPD_WORK_ORDER` / `_UPD_PRODUCTION_REPORT` | "Document was updated" notifications consumed by background workers (totals recalculation, downstream invalidations). | | `ERP_JMS_ACTIVEMQ_DEL_SALE_ORDER` / `_DEL_WORK_ORDER` / `_DEL_PRODUCTION_REPORT` | Document-delete notifications. | ### Element-master change fan-out (7) — `CHANGE_ELE_*` | Constant | Purpose | |---|---| | `_CHANGE_ELE_CUSTOMER` | Customer-master change. | | `_CHANGE_ELE_EMPLOYEE` | Employee-master change. | | `_CHANGE_ELE_MACHINE` | Shop-floor machine-master change. | | `_CHANGE_ELE_MATERIALS` | Materials-master change. | | `_CHANGE_ELE_PRODUCT` | Product-master change. | | `_CHANGE_ELE_PROCESS` | Process-master change. | | `_CHANGE_ELE_TEAM` | Team-master change. | ### System-info / lookup-table change fan-out (9) — `CHANGE_SIS_*` | Constant | Purpose | |---|---| | `_CHANGE_SIS_CUSTOMER_CLASSIFY` | Customer-classification change. | | `_CHANGE_SIS_DELIVER` | Delivery-method change. | | `_CHANGE_SIS_FORMULA` | Calculation-formula change. | | `_CHANGE_SIS_PAYMENT` | Payment-method change. | | `_CHANGE_SIS_PROCESS_CLASSIFY` | Process-classification change. | | `_CHANGE_SIS_PRODUCT_CLASSIFY` | Product-classification change. | | `_CHANGE_SIS_SALES_MAN` | Sales-personnel change. | | `_CHANGE_SIS_TAX` | Tax-rate change. | | `_CHANGE_SIS_WORK_CENTER` | Work-centre change. | (Constant prefixes elided to `_…` after the first table — the full literal is `ERP_JMS_ACTIVEMQ_…`.) ### Listener side `xlyErpJmsConsumer/.../consumer/Consumer.java` is a single class that hosts **all 24 `@JmsListener` methods** — one per destination. Each method dispatches the payload to a corresponding `Consumer*Thread` class under `xlyErpJmsConsumer/.../thread/`, which executes the domain-specific work (typically calling a `PRO_ERPMERGEBASE*` stored proc that consolidates per-tenant rows into a flattened base lookup table) asynchronously. There is *one* listener class with 24 methods, *not* 24 listener classes. None of the consumer threads invoke `@CacheEvict` or `cleanRedis*` — Redis cache invalidation is synchronous in BACK during save, see [cache-invalidation.md](../reference/maintainer/cache-invalidation.md). ## RocketMQ — other flows `RocketMQServiceImpl` and its companion `RocketMQService` interface sit in `xlyBusinessService/src/main/java/com/xly/service/`. They cover non-cache-invalidation flows (for example, `MQCompensateServiceImpl` handles compensation/retry semantics that ActiveMQ's destinations don't express well). RocketMQ topics are configured per environment. ## Manual cache-invalidation poke If a metadata change happens via raw SQL (no JMS event), the cache across nodes will not bust automatically. The supported override is `BusinessCleanRedisDataImpl` in `xlyBusinessService/.../service/impl/` — it can publish an invalidation event directly. See [cache invalidation on metadata change](../reference/maintainer/cache-invalidation.md) for the broader troubleshooting path. ## What this is *not* - **Not a public integration channel.** External integrators do not publish or subscribe to these brokers. They are *internal* fan-out for the cluster. - **Not the only way to invalidate caches.** The HTTP write paths in `xlyEntry` already publish JMS events when they should; the manual poke is for edge cases.