Improve event delivery and ZeroMQ queue configuration
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 48/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- java
- Domain
- backend, distributed-systems
Research direction
Start with RealtimeEventService.add() and work(), then trace how BlockEventLoad produces events and how queue pressure could pause and resume loading. Inspect NativeMessageQueue.start() in useNativeQueue mode, focusing on when SndHWM is configured relative to socket creation. Done means pending events apply backpressure without drops and sendQueueLength controls the publisher queue.
Written by the indexing model from the issue text.
Description
Summary
The event service has two issues affecting reliability and configurability:
RealtimeEventServiceuses an unboundedLinkedBlockingQueuewith an application-level 10,000-entry soft limit. Once that threshold is reached, new events are dropped instead of applying backpressure.NativeMessageQueuesets the send high-water mark (SndHWM) only after creating the socket, causing the configured send queue length to be ineffective.
We recommend introducing explicit backpressure between RealtimeEventService and BlockEventLoad, and correcting the timing of the SndHWM configuration.
Root Cause
1. RealtimeEventService drops events when the queue is full without applying backpressure
The queue is an unbounded LinkedBlockingQueue, and a single-threaded scheduler calls work() once per second to consume events in batches. The producer-side add() logic is:
public void add(Event event) {
if (queue.size() >= maxEventSize) { // maxEventSize = 10000
logger.warn("Add event failed, blockId {}.", ...);
return; // Drop the event directly
}
queue.offer(event);
}
When downstream consumption (work(), which runs once per second) cannot keep up with the event production rate and the queue reaches 10,000 entries, subsequent events are dropped directly, with only a warning being logged.
This is a drop-when-full strategy rather than a backpressure mechanism that applies pressure to the producer. Events generated while the queue is full are therefore silently lost.
2. NativeMessageQueue sets SndHWM too late, causing the configuration to be ineffective
In start(), the PUB socket is created first, and context.setSndHWM(sendQueueLength) is called afterward.
In ZeroMQ (JeroMQ), ZContext.setSndHWM only affects sockets created after the context-level setting is applied. The high-water mark is applied to the socket when it is created, so changing the context value afterward does not affect an already-created publisher socket.
As a result, the configured sendQueueLength is silently ignored, and the publisher continues to use the default high-water mark of 1000.
Reproduction
1. RealtimeEventService
Slow down downstream event consumption so that the event production rate remains higher than the consumption rate of once per second.
Once the queue reaches 10,000 entries, observe that subsequent events are dropped, with only an Add event failed warning being logged. The dropped events cannot be recovered.
2. NativeMessageQueue
In useNativeQueue mode, configure an explicit sendQueueLength. After startup, inspect the actual send high-water mark of the publisher.
The actual value remains at the default of 1000 instead of the configured value.
Impact
RealtimeEventService: When downstream consumption slows down, events beyond the 10,000-entry queue limit are silently dropped, causing real-time event loss and potentially resulting in subscribers missing events. The current drop-when-full + log strategy does not propagate backpressure to upstream producers.NativeMessageQueue: The configured send queue length is ineffective, preventing operators from controlling the publisher's send queue through configuration. When downstream consumption slows down and pending messages exceed the default high-water mark, excess messages may be dropped directly by the PUB socket, again resulting in silent event loss. The affected scope is limited touseNativeQueuemode.- Both issues affect the reliability and configurability of event delivery. They do not affect consensus or asset security.
Suggested Fix
-
RealtimeEventService: Introduce an explicit backpressure mechanism, such as anisBusy()method. When the number of pending events reaches the configured threshold,BlockEventLoadshould pause loading new events and resume once the queue size falls below the recovery threshold. This prevents events from being dropped when the queue reaches a fixed limit. -
NativeMessageQueue: Move thesetSndHWMconfiguration to before the socket is created, or directly callsetSndHWM(sendQueueLength)on the socket itself, so that the configured value takes effect.
- Dominant language
- Java
- Stars
- 4.2k
- Forks
- 1.7k
- Avg merge
- 6d 20h
- Merged PRs (30d)
- 14
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from tronprotocol/java-tron
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
tronprotocol/java-tron#6969 · 8 comments ·
-
type:feature
Difficulty 5/5 Over a week Newbie friendliness 48/100
tronprotocol/java-tron#6963 · 6 comments ·
-
type:feature
Difficulty 5/5 Over a week Newbie friendliness 28/100
tronprotocol/java-tron#6959 · 3 comments ·
-
type:feature
Difficulty 5/5 Over a week Newbie friendliness 38/100
tronprotocol/java-tron#6958 · 3 comments ·
-
topic:release type:tracking
Difficulty 4/5 3-5 days Newbie friendliness 35/100
tronprotocol/java-tron#6957 · 2 comments ·
All issues in tronprotocol/java-tron
Similar issues
-
Bug Java Platform: Java
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
getsentry/sentry-java#6138 · 1 comment ·
-
bug needs triage p2
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
GoogleCloudPlatform/DataflowTemplates#4273 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
bug needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 76/100