• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In
Build has been canceled!

Hyshmily / hotkey / 28916241081

08 Jul 2026 03:53AM UTC coverage: 89.468% (-0.7%) from 90.12%
28916241081

push

github

Hyshmily
refactor(core): extract central dispatcher and broadcast buffer

Introduce CentralDispatcher for centralized event routing and BroadcastBuffer for cache synchronization. Refactor HotKeyCache, SlidingWindowDetector, and related components to use the new dispatching mechanism, improving separation of concerns and reducing coupling.

Signed-off-by: Hyshmily <cxm8607@outlook.com>

1328 of 1564 branches covered (84.91%)

Branch coverage included in aggregate %.

102 of 134 new or added lines in 17 files covered. (76.12%)

3 existing lines in 2 files now uncovered.

3769 of 4133 relevant lines covered (91.19%)

4.21 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.57
/common/src/main/java/io/github/hyshmily/hotkey/cache/CentralDispatcher.java
1
/*
2
 * Copyright 2026 Hyshmily. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package io.github.hyshmily.hotkey.cache;
17

18
import static io.github.hyshmily.hotkey.constants.HotKeyConstants.TOPK_INCR;
19
import static io.github.hyshmily.hotkey.sync.local.SyncMessage.*;
20

21
import io.github.hyshmily.hotkey.Internal;
22
import io.github.hyshmily.hotkey.cache.cachesupport.BroadcastBuffer;
23
import io.github.hyshmily.hotkey.hotkeydetector.HotKeyDetector;
24
import io.github.hyshmily.hotkey.reporting.KeyReporter;
25
import io.github.hyshmily.hotkey.sync.local.CacheSyncPublisher;
26
import io.github.hyshmily.hotkey.sync.local.SyncMessage;
27
import java.util.Collection;
28
import java.util.Optional;
29
import lombok.RequiredArgsConstructor;
30
import lombok.extern.slf4j.Slf4j;
31

32
/**
33
 * Central dispatch for all external communication from the HotKey cache layer.
34
 * <p>
35
 * Aggregates three responsibilities that were previously spread across
36
 * {@link HotKeyCache}:
37
 * <ul>
38
 *   <li>Reporting key accesses to the Worker via {@link KeyReporter}</li>
39
 *   <li>Broadcasting INVALIDATE/REFRESH operations to peer instances
40
 *       via {@link CacheSyncPublisher}</li>
41
 *   <li>Deferred buffering of REFRESH messages via {@link BroadcastBuffer}</li>
42
 * </ul>
43
 * <p>
44
 * This reduces {@link HotKeyCache}'s constructor dependencies and centralizes
45
 * all "where to send this message" decisions in one place.
46
 */
47
@RequiredArgsConstructor
48
@Slf4j
4✔
49
@Internal
50
public class CentralDispatcher {
51

52
  @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
53
  private final Optional<KeyReporter> hotKeyReporter;
54

55
  @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
56
  private final Optional<CacheSyncPublisher> cacheSyncPublisher;
57

58
  private final BroadcastBuffer broadcastBuffer;
59

60
  private final HotKeyDetector hotKeyDetector;
61

62
  private static final String NO_SYNC_PUBLISHER = "No sync publisher found, please enable hotkey.sync";
63

64
  /**
65
   * Increment the local hot-key detector counter and optionally report the
66
   * access to the Worker via the {@link KeyReporter}.
67
   *
68
   * @param cacheKey       the accessed cache key
69
   * @param isSkipBroadcast if {@code true}, skip reporting to Worker
70
   */
71
  @SuppressWarnings("java:S6213")
72
  public void record(String cacheKey, boolean isSkipBroadcast) {
73
    hotKeyDetector.add(cacheKey, TOPK_INCR);
5✔
74
    if (!isSkipBroadcast) {
2✔
75
      hotKeyReporter.ifPresent(r -> r.record(cacheKey));
9✔
76
    }
77
  }
1✔
78

79
  /**
80
   * Broadcast a sync operation to all peer instances.
81
   * <p>
82
   * The actual broadcast method invoked on {@link CacheSyncPublisher} depends
83
   * on the operation type:
84
   * <ul>
85
   *   <li>{@link SyncMessage#TYPE_INVALIDATE} — calls
86
   *       {@link CacheSyncPublisher#broadcastLocalInvalidate}</li>
87
   *   <li>{@link SyncMessage#TYPE_REFRESH} — buffers via
88
   *       {@link BroadcastBuffer#record} for deferred flush</li>
89
   * </ul>
90
   *
91
   * @param cacheKey the affected cache key
92
   * @param type     the operation type ({@link SyncMessage#TYPE_INVALIDATE}
93
   *                 or {@link SyncMessage#TYPE_REFRESH})
94
   * @param version  the data version at which the operation occurred
95
   * @param degraded whether the version was obtained in degraded mode
96
   * @throws IllegalArgumentException if the type is unknown
97
   */
98
  public void broadcast(String cacheKey, String type, long version, boolean degraded) {
99
    switch (type) {
8!
100
      case TYPE_INVALIDATE -> cacheSyncPublisher.ifPresentOrElse(
9✔
101
        p -> p.broadcastLocalInvalidate(cacheKey, version, degraded),
6✔
102
        () -> log.debug("broadcast INVALIDATE: {}", NO_SYNC_PUBLISHER)
5✔
103
      );
104
      case TYPE_REFRESH -> cacheSyncPublisher.ifPresent(p -> broadcastBuffer.record(cacheKey, version, degraded));
16✔
NEW
105
      default -> throw new IllegalArgumentException("Unknown broadcast type: " + type);
×
106
    }
107
  }
1✔
108

109
  /**
110
   * Batch-broadcast a sync operation for multiple keys.
111
   * <p>
112
   * Currently only supports {@link SyncMessage#TYPE_INVALIDATE_ALL}:
113
   * calls {@link CacheSyncPublisher#broadcastLocalInvalidateAll}.
114
   *
115
   * @param cacheKeys the keys to broadcast; null or empty is silently ignored
116
   * @param type      the operation type ({@link SyncMessage#TYPE_INVALIDATE_ALL})
117
   */
118
  public void broadcast(Collection<String> cacheKeys, String type) {
119
    if (cacheKeys == null || cacheKeys.isEmpty()) {
5!
NEW
120
      return;
×
121
    }
122
    if (type.equals(TYPE_INVALIDATE_ALL)) {
4!
123
      cacheSyncPublisher.ifPresent(p -> p.broadcastLocalInvalidateAll(cacheKeys));
9✔
124
    }
125
  }
1✔
126
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc