Skip to content

Commit 20d31d6

Browse files
committed
Heartbeat :)
1 parent 245a000 commit 20d31d6

File tree

2 files changed

+83
-1
lines changed

2 files changed

+83
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,4 @@ swetrix.track("my_custom_event", false); // You can also track custom events.
3737
## TODO
3838
- [x] Page View Tracking
3939
- [x] Custom Event Tracking
40-
- [ ] Heartbeats
40+
- [x] Heartbeats

src/main/java/co/casterlabs/swetrix/Swetrix.java

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.IOException;
44
import java.util.Locale;
55
import java.util.TimeZone;
6+
import java.util.concurrent.TimeUnit;
67

78
import co.casterlabs.rakurai.json.element.JsonObject;
89
import lombok.AccessLevel;
@@ -14,9 +15,13 @@
1415
import xyz.e3ndr.fastloggingframework.logging.LogLevel;
1516

1617
public class Swetrix {
18+
private static final long HEARTBEAT_INTERVAL = TimeUnit.SECONDS.toMillis(25);
19+
1720
private FastLogger logger;
1821
private Builder config;
1922

23+
private Thread heartbeatThread;
24+
2025
private boolean hasStartedSession = false;
2126

2227
static {
@@ -155,6 +160,83 @@ public void trackPageView(@NonNull String page, @NonNull String locale) {
155160
}
156161
}
157162

163+
/* ---------------- */
164+
/* Heartbeat */
165+
/* ---------------- */
166+
167+
private void sendHB() {
168+
if (this.config.analyticsDisabled) {
169+
this.logger.debug("Analytics are disabled, not sending heartbeat.");
170+
return;
171+
}
172+
173+
try {
174+
JsonObject response = HttpUtil.post(
175+
this.config.apiUrl + "/hb",
176+
new JsonObject()
177+
.put("pid", this.config.projectId)
178+
);
179+
180+
if (response == null) {
181+
// All good!
182+
this.logger.debug("Successfully sent heartbeat event.");
183+
return;
184+
}
185+
186+
String error = response.getString("error");
187+
String errorMessage = response.getString("message");
188+
189+
this.logger.severe("An API error occurred:\n%s: %s", error, errorMessage);
190+
} catch (IOException e) {
191+
this.logger.severe("An error occurred whilst making API call:\n%s", e);
192+
}
193+
}
194+
195+
/**
196+
* Starts the heartbeat signal. This is for the "Live visitors" statistic and
197+
* must be started manually by you.
198+
*
199+
* @apiNote In order for this event to be counted correctly, you must call
200+
* {@link #trackPageView(String)} or
201+
* {@link #trackPageView(String, String)} for the client session to be
202+
* started.
203+
*
204+
* @see #stopHeartbeat()
205+
*/
206+
public void startHeartbeat() {
207+
assert this.hasStartedSession : "You must call trackPageView() first in order for the user session to be created.";
208+
209+
if (this.heartbeatThread != null) return;
210+
211+
this.heartbeatThread = new Thread(() -> {
212+
Thread current = Thread.currentThread();
213+
214+
while (!current.isInterrupted()) {
215+
this.sendHB();
216+
217+
try {
218+
Thread.sleep(HEARTBEAT_INTERVAL);
219+
} catch (InterruptedException e) {}
220+
}
221+
});
222+
this.heartbeatThread.setName("Swetrix Heartbeat Thread");
223+
this.heartbeatThread.setPriority(Thread.MIN_PRIORITY);
224+
this.heartbeatThread.setDaemon(true);
225+
this.heartbeatThread.start();
226+
}
227+
228+
/**
229+
* Stops the hearbeat signal.
230+
*
231+
* @see #startHeartbeat()
232+
*/
233+
public void stopHeartbeat() {
234+
if (this.heartbeatThread == null) return;
235+
236+
this.heartbeatThread.interrupt();
237+
this.heartbeatThread = null;
238+
}
239+
158240
/* ---------------- */
159241
/* Builder */
160242
/* ---------------- */

0 commit comments

Comments
 (0)