You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Update config pages for 4.3.1.4
* Break config banner descriptions only at sentence boundaries
Section banners joined every line of the source YAML comment with <br />,
so a comment that merely soft-wraps mid-sentence rendered with a line break
in the middle of a clause. A line now continues the previous one unless it
starts a new sentence.
- Add _join_description_lines to generate_config_pages.py (PR #635)
- Regenerate the PE core and rule engine config page from release/license/4.3
Claude-Session: https://claude.ai/code/session_018dTDP6H5jC98e2QFZ5GgXG
Copy file name to clipboardExpand all lines: src/content/docs/docs/pe/reference/configuration/core-rule-engine-config.mdx
+57-5Lines changed: 57 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -411,9 +411,9 @@ import Banner from '~/components/Banner.astro';
411
411
</div>
412
412
</div>
413
413
414
-
## Database telemetry parameters
414
+
## Database parameters
415
415
416
-
<Bannervariant="pe">Selects the storage backend (SQL, Cassandra, or TimescaleDB) for time-series and latest telemetry data, and sets the maximum query intervals.</Banner>
416
+
<Bannervariant="pe">Selects the storage backend (SQL, Cassandra, or TimescaleDB) for time-series and latest telemetry data and the maximum query intervals, and configures optional Citus (distributed PostgreSQL) support.</Banner>
417
417
418
418
<divclass="config-def-list">
419
419
<divclass="config-def-item">
@@ -428,6 +428,42 @@ import Banner from '~/components/Banner.astro';
<pclass="config-def-desc">Enable optional Citus (distributed PostgreSQL) support. PE only. Default: plain PostgreSQL. This is far more than distributing attribute_kv and ts_kv_latest: enabling it hash-distributes device, asset, entity_view (by id) and alarm, entity_alarm (by originator_id), rewrites the alarm-group primary keys to include the distribution column, drops the unique constraints that are incompatible with the chosen distribution, and converts ~25 dimension tables (relation, key_dictionary, device/asset profiles, etc.) into replicated reference tables. See CitusTables for the authoritative list of distributed/reference tables. Because the distribution is applied to live schema, this is effectively a one-way switch: plan to (re)create the database with Citus in mind.</p>
<p class="config-def-desc">Number of Citus shards for the hash-distributed tables. Fixed at distribution time; size >= max expected worker count, ideally a multiple of it. CONNECTION POOL SIZING: with Citus enabled, the attribute_kv and ts_kv_latest write queues each use shard_count writer threads (one queue per shard, so each batch targets a single shard) INSTEAD OF sql.attributes.batch_threads / sql.ts_latest.batch_threads. That is 2 * shard_count KV-writer threads in total, each borrowing a coordinator JDBC connection while draining its batch (one shard per batch => one worker connection per flush). The default spring.datasource.hikari.maximumPoolSize of 16 is undersized for Citus and will stall writes: raise it via SPRING_DATASOURCE_MAXIMUM_POOL_SIZE. At peak all 2 * shard_count writer threads can flush at once, so to guarantee writers never wait, size maximumPoolSize >= 2 * shard_count + headroom for the rest of the app (entity DAO, rule engine, REST, EDQS) — e.g. ~64 + ~16 = ~80 for shard_count=32. Each thread holds a connection only briefly while flushing its batch, so a smaller pool often suffices in practice; tune it down/up by watching the HikariCP pending-connection count under peak ingestion. Also ensure the Citus workers' connection limits accommodate maximumPoolSize * worker_count. Note that each of the two KV queues spawns exactly one flush thread per shard bucket, so both writer-thread count and peak connection demand scale as 2 * shard_count per app instance. Raising shard_count for finer rebalance granularity therefore also multiplies KV writer threads and their connection footprint; a bounded flush pool decoupling thread count from shard_count is a possible future optimization. When smart_routing.enabled=true (the default when Citus is on), the KV read+write path shifts OFF the coordinator pool onto the per-worker pools (smart_routing.worker_pool_size), so the coordinator maximumPoolSize pressure from the KV path is correspondingly reduced — but each worker now needs its own pool sized for the shards it owns (see the worker_pool_size comment below).</p>
<pclass="config-def-desc">Connect directly to the Citus worker owning a shard for single-shard KV ops instead of routing via the coordinator. Defaults to database.citus.enabled.</p>
<p class="config-def-desc">Per-worker Hikari pool size for direct worker connections. Small pools for short single-shard ops. SIZING: a single worker owns roughly shard_count / worker_count shards, and up to that many per-shard write-queue threads can flush to that one worker concurrently. If worker_pool_size is smaller, concurrent flushes wait up to worker_connection_timeout_ms and, on timeout, the routed flush FAILS (no fallback). Size worker_pool_size >= ceil(shard_count / min_expected_worker_count) plus headroom for the single-entity routed reads. Tradeoff: total worker connection budget is worker_pool_size * worker_count * app_instances connections landing on each worker's max_connections, so do not oversize. Default 8 suits shard_count=32 with >=6 workers; raise it for fewer/heavier-loaded workers. READ SIZING: single-entity routed reads (rule-engine attribute/latest lookups) share this same per-worker pool with up to 2 * shard_count / worker_count concurrent write flushes for that worker. A read that cannot borrow within worker_connection_timeout_ms FAILS outright (there is no coordinator fallback for a routed read), so size the pool for read bursts riding on top of the flush bursts.</p>
<pclass="config-def-desc">How often (ms) to refresh shard placements (bucket->worker). Placements move on rebalance; a stale placement is correctness-safe (Citus MX forwards to the true owner). The same cadence also drives worker-pool reconciliation: adding pools for newly seen workers, retiring pools for departed ones, and the endpoint-drift self-heal that rebuilds a worker's pool after it re-addresses (e.g. a worker IP change). Lower this to speed recovery after a worker re-address.</p>
<pclass="config-def-desc">Connection timeout (ms) for direct worker pools; bounds the boot reachability probe and runtime borrow-wait — keep short for fail-fast.</p>
<p class="config-def-desc">FAILOVER STORY (HA workers, e.g. Patroni leader+replica pairs): when a worker leader is demoted, the HA manager rewrites pg_dist_node to the new leader and the pools self-heal without waiting for the scheduled refresh tick. Worker pools are unconditionally hardened against non-writable (standby / read-only) servers: pool URLs pin targetServerType=primary (the driver refuses to connect to a read-only server) and pooled connections are write-validated at borrow, so connections pinned to a demoted leader are evicted immediately. On top of that, the first routed operation failing with a failover signature (SQLSTATE 25006 "read-only transaction", or a worker connection-acquisition failure) triggers an immediate asynchronous catalog refresh + pool reconcile. This knob debounces that trigger: at most one error-triggered refresh runs per window, so a burst of failing operations collapses into a single refresh and there is no refresh storm while the catalog has not flipped to the new leader yet (the scheduled placement_refresh_interval_ms tick remains the backstop).</p>
<pclass="config-def-desc">Citus-only defensive cap on how many entity ids a relation/reference recursion may materialize on the coordinator heap before binding. A breach fails the query with an error naming this property instead of risking a coordinator out-of-memory condition.</p>
466
+
</div>
431
467
</div>
432
468
433
469
## Cassandra driver configuration parameters
@@ -664,7 +700,7 @@ import Banner from '~/components/Banner.astro';
<pclass="config-def-desc">batch thread count has to be a prime number like 3 or 5 to gain perfect hash distribution</p>
703
+
<pclass="config-def-desc">batch thread count has to be a prime number like 3 or 5 to gain perfect hash distribution. When database.citus.enabled=true this is overridden by database.citus.shard_count (see that property for pool sizing)</p>
<pclass="config-def-desc">batch thread count has to be a prime number like 3 or 5 to gain perfect hash distribution</p>
747
+
<pclass="config-def-desc">batch thread count has to be a prime number like 3 or 5 to gain perfect hash distribution. When database.citus.enabled=true this is overridden by database.citus.shard_count (see that property for pool sizing)</p>
<pclass="config-def-desc">Prefix prepended to every Redis cache key by the transactional cache base. Empty by default. Useful when several environments share one Redis instance (e.g. a Redis Cluster where the redis.db logical-database isolation is unavailable) and must not collide on cache keys.</p>
<pclass="config-def-desc">make sure that if cache.type is 'redis' and cache.attributes.enabled is 'true' if you change 'maxmemory-policy' Redis config property to 'allkeys-lru', 'allkeys-lfu' or 'allkeys-random'</p>
@@ -1289,6 +1329,10 @@ import Banner from '~/components/Banner.astro';
<pclass="config-def-desc">Will enable cache-aside strategy for SQL timeseries latest DAO. make sure that if cache.type is 'redis' and cache.ts_latest.enabled is 'true' if you change 'maxmemory-policy' Redis config property to 'allkeys-lru', 'allkeys-lfu' or 'allkeys-random'</p>
@@ -1931,7 +1983,7 @@ import Banner from '~/components/Banner.astro';
1931
1983
1932
1984
## Spring CORS configuration parameters.
1933
1985
1934
-
<Bannervariant="pe">Controls the Access-Control-Allow-Origin and Access-Control-Allow-Credentials response headers.<br /> WARNING: The default configuration allows cross-origin requests from ANY domain with credentials.<br /> This means any website can make API requests on behalf of an authenticated user if the token<br /> is accessible (e.g., via XSS). For production deployments, restrict to your domain(s):<br /> TB_CORS_ALLOWED_ORIGIN_PATTERNS={'https://your-domain.com'}<br /> For multi-domain deployments, list all allowed domains comma-separated:<br /> TB_CORS_ALLOWED_ORIGIN_PATTERNS={'https://domain1.com,https://domain2.com'}</Banner>
1986
+
<Bannervariant="pe">Controls the Access-Control-Allow-Origin and Access-Control-Allow-Credentials response headers.<br /> WARNING: The default configuration allows cross-origin requests from ANY domain with credentials.<br /> This means any website can make API requests on behalf of an authenticated user if the token is accessible (e.g., via XSS). For production deployments, restrict to your domain(s):<br /> TB_CORS_ALLOWED_ORIGIN_PATTERNS={'https://your-domain.com'}<br /> For multi-domain deployments, list all allowed domains comma-separated:<br /> TB_CORS_ALLOWED_ORIGIN_PATTERNS={'https://domain1.com,https://domain2.com'}</Banner>
0 commit comments