Skip to content

Commit db97b38

Browse files
committed
fix stopping session
1 parent b539fe3 commit db97b38

File tree

13 files changed

+577
-40
lines changed

13 files changed

+577
-40
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
- name: Build and publish with Gradle
2828
uses: gradle/actions/setup-gradle@v3
2929
with:
30-
arguments: --no-daemon -i -PprojVersion=${{ env.VERSION }} jreleaserConfig build test publish
30+
arguments: --no-daemon -i -PprojVersion=${{ env.VERSION }} jreleaserConfig :build :test :publish
3131
env:
3232
JRELEASER_GPG_SECRET_KEY: ${{ secrets.JRELEASER_GPG_SECRET_KEY }}
3333
JRELEASER_GPG_PASSPHRASE: ${{ secrets.JRELEASER_GPG_PASSPHRASE }}

README.md

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ Session session = new Session();
3737
session.setName("My Session");
3838

3939
// Add tags if needed
40-
session.addTag("production");
41-
session.addTag("v1.0.0");
42-
session.addTag("feature:session-recording");
40+
session.addTag("environment", "production");
41+
session.addTag("version", "v1.0.0");
42+
session.addTag("feature", "session-recording");
4343

4444
// Add session attributes
4545
session.addSessionAttribute("userId", "12345");
@@ -69,15 +69,15 @@ if (!SessionRecorder.isInitialized()) {
6969
// Start a continuous session
7070
Session session = new Session();
7171
session.setName("Continuous Session");
72-
session.addTag("continuous");
73-
session.addTag("debug-mode");
72+
session.addTag("mode", "continuous");
73+
session.addTag("type", "debug");
7474

7575
SessionRecorder.start(SessionType.CONTINUOUS, session)
7676
.thenRun(() -> {
7777
// Save data to continuous session
7878
Session sessionData = new Session();
7979
sessionData.setName("Updated Data");
80-
sessionData.addTag("saved");
80+
sessionData.addTag("status", "saved");
8181
SessionRecorder.save(sessionData);
8282
});
8383

@@ -88,3 +88,24 @@ SessionRecorder.stop(session);
8888
SessionRecorder.cancel();
8989
```
9090

91+
## Examples
92+
93+
See the `examples/` directory for comprehensive examples demonstrating:
94+
95+
- Basic session recording
96+
- Continuous sessions
97+
- Error handling
98+
- Async operations
99+
100+
To run the examples:
101+
102+
```bash
103+
# Build the main library first
104+
./gradlew build
105+
106+
# Run the examples
107+
./gradlew :examples:run
108+
```
109+
110+
**Note:** The examples are for documentation purposes and are not included in the published library JAR.
111+

examples/README.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Session Recorder Examples
2+
3+
This directory contains example code demonstrating how to use the Session Recorder library.
4+
5+
## Running the Examples
6+
7+
### Prerequisites
8+
9+
1. Make sure you have the main library built:
10+
```bash
11+
./gradlew build
12+
```
13+
14+
2. Update the API key in `Example.java`:
15+
```java
16+
static class Config {
17+
public static final String MULTIPLAYER_OTLP_KEY = "your-actual-api-key-here";
18+
}
19+
```
20+
21+
### Building the Examples
22+
23+
```bash
24+
./gradlew :examples:build
25+
```
26+
27+
### Running the Main Example
28+
29+
```bash
30+
./gradlew :examples:run
31+
```
32+
33+
### Running Specific Examples
34+
35+
The `Main.java` file contains multiple example methods:
36+
37+
- `main()` - Basic session recording example
38+
- `continuousSessionExample()` - Continuous session example
39+
- `errorHandlingExample()` - Error handling example
40+
41+
You can modify the `main()` method to call different examples:
42+
43+
```java
44+
public static void main(String[] args) {
45+
// Run basic example
46+
// mainExample();
47+
48+
// Run continuous session example
49+
continuousSessionExample();
50+
51+
// Run error handling example
52+
// errorHandlingExample();
53+
}
54+
```
55+
56+
## Example Features Demonstrated
57+
58+
- ✅ Session initialization and configuration
59+
- ✅ Resource attributes and session attributes
60+
- ✅ Tags management
61+
- ✅ Plain and continuous sessions
62+
- ✅ Error handling and session cancellation
63+
- ✅ Async operations with CompletableFuture
64+
65+
## Note
66+
67+
These examples are for documentation purposes and are not included in the published library JAR.

examples/build.gradle

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
plugins {
2+
id 'java'
3+
id 'application'
4+
id 'com.github.johnrengelman.shadow' version '8.1.1'
5+
}
6+
7+
group = 'app.multiplayer.session_recorder'
8+
version = '0.0.1'
9+
10+
repositories {
11+
mavenCentral()
12+
mavenLocal()
13+
}
14+
15+
dependencies {
16+
implementation project(':') // Depend on the main library
17+
implementation 'io.opentelemetry:opentelemetry-api:1.35.0'
18+
implementation 'io.opentelemetry:opentelemetry-sdk:1.35.0'
19+
implementation 'io.opentelemetry:opentelemetry-sdk-logs:1.35.0'
20+
implementation 'io.opentelemetry:opentelemetry-exporter-otlp:1.35.0'
21+
implementation 'io.opentelemetry:opentelemetry-exporter-common:1.35.0'
22+
}
23+
24+
application {
25+
mainClass = 'app.multiplayer.session_recorder.Main'
26+
}
27+
28+
jar {
29+
manifest {
30+
attributes 'Main-Class': 'app.multiplayer.session_recorder.Main'
31+
}
32+
}
33+
34+
shadowJar {
35+
archiveBaseName.set('examples')
36+
archiveClassifier.set('')
37+
archiveVersion.set('0.0.1')
38+
mergeServiceFiles()
39+
}
40+
41+
42+
43+
java {
44+
sourceCompatibility = JavaVersion.VERSION_11
45+
targetCompatibility = JavaVersion.VERSION_11
46+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package app.multiplayer.session_recorder;
2+
3+
public class Config {
4+
public static String SERVICE_NAME = System.getenv("SERVICE_NAME") != null && !System.getenv("SERVICE_NAME").isEmpty()
5+
? System.getenv("SERVICE_NAME")
6+
: "dialogue-hub";
7+
public static String SERVICE_VERSION = System.getenv("SERVICE_VERSION") != null && !System.getenv("SERVICE_VERSION").isEmpty()
8+
? System.getenv("SERVICE_VERSION")
9+
: "0.0.1";
10+
public static String PLATFORM_ENV = System.getenv("PLATFORM_ENV") != null && !System.getenv("PLATFORM_ENV").isEmpty()
11+
? System.getenv("PLATFORM_ENV")
12+
: "staging";
13+
14+
public static double MULTIPLAYER_OTLP_SPAN_RATIO = System.getenv("MULTIPLAYER_OTLP_SPAN_RATIO") != null && !System.getenv("MULTIPLAYER_OTLP_SPAN_RATIO").isEmpty()
15+
? Double.parseDouble(System.getenv("MULTIPLAYER_OTLP_SPAN_RATIO"))
16+
: 0.01;
17+
18+
19+
public static String MULTIPLAYER_OTLP_KEY = System.getenv("MULTIPLAYER_OTLP_KEY") != null && !System.getenv("MULTIPLAYER_OTLP_KEY").isEmpty()
20+
? System.getenv("MULTIPLAYER_OTLP_KEY")
21+
: "";
22+
public static String OTLP_TRACES_ENDPOINT = System.getenv("OTLP_TRACES_ENDPOINT") != null && !System.getenv("OTLP_TRACES_ENDPOINT").isEmpty()
23+
? System.getenv("OTLP_TRACES_ENDPOINT")
24+
: "https://api.multiplayer.app/v1/traces";
25+
public static String OTLP_LOGS_ENDPOINT = System.getenv("OTLP_LOGS_ENDPOINT") != null && !System.getenv("OTLP_LOGS_ENDPOINT").isEmpty()
26+
? System.getenv("OTLP_LOGS_ENDPOINT")
27+
: "https://api.multiplayer.app/v1/logs";
28+
29+
public static String VAULT_OF_TIME_SERVICE_URL = System.getenv("VAULT_OF_TIME_SERVICE_URL");
30+
public static String EPOCH_ENGINE_SERVICE_URL = System.getenv("EPOCH_ENGINE_SERVICE_URL");
31+
public static String MINDS_OF_TIME_SERVICE_URL = System.getenv("MINDS_OF_TIME_SERVICE_URL");
32+
}
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
package app.multiplayer.session_recorder;
2+
3+
import app.multiplayer.session_recorder.type.SessionRecorderConfig;
4+
import app.multiplayer.session_recorder.type.Session;
5+
import app.multiplayer.session_recorder.type.SessionType;
6+
import app.multiplayer.session_recorder.trace.SessionRecorderRandomIdGenerator;
7+
8+
import java.util.concurrent.CompletableFuture;
9+
10+
/**
11+
* Example demonstrating how to use the SessionRecorder library
12+
*/
13+
public class Main {
14+
15+
// Using the Config class from the same package
16+
17+
public static void main(String[] args) {
18+
System.out.println("🚀 Starting Multiplayer Time Travel CLI App...");
19+
20+
try {
21+
// Initialize SessionRecorder
22+
SessionRecorderConfig config = new SessionRecorderConfig();
23+
config.setApiKey(Config.MULTIPLAYER_OTLP_KEY);
24+
config.setTraceIdGenerator(OpenTelemetry.getIdGenerator());
25+
26+
SessionRecorder.init(config);
27+
System.out.println("✅ SessionRecorder initialized successfully");
28+
29+
// Create and configure session
30+
Session session = new Session();
31+
32+
// Add resource attributes (service-level metadata)
33+
session.addResourceAttribute("service.name", "my-service");
34+
session.addResourceAttribute("service.version", "1.0.0");
35+
session.addResourceAttribute("deployment.environment", "production");
36+
session.addResourceAttribute("host.name", "server-01");
37+
38+
// Add session attributes (session-specific data)
39+
session.addSessionAttribute("userId", "12345");
40+
session.addSessionAttribute("environment", "production");
41+
session.addSessionAttribute("version", "1.0.0");
42+
session.addSessionAttribute("feature", "session-recording");
43+
44+
// Add tags
45+
// session.addTag("environment", "production");
46+
// session.addTag("version", "v1.0.0");
47+
// session.addTag("feature", "session-recording");
48+
session.setName("Multiplayer Time Travel CLI Session");
49+
50+
System.out.println("📡 Starting session recording...");
51+
52+
// Start session recording and await the result
53+
try {
54+
// SessionRecorder.start returns a CompletableFuture
55+
CompletableFuture<Void> startFuture = SessionRecorder.start(SessionType.PLAIN, session);
56+
startFuture.join(); // Wait for completion
57+
System.out.println("✅ Session recording started successfully");
58+
59+
// Simulate some work
60+
System.out.println("🔄 Performing some work...");
61+
Thread.sleep(2000); // Simulate 2 seconds of work
62+
63+
// Stop the session
64+
System.out.println("🛑 Stopping session recording...");
65+
Session stopSession = new Session();
66+
stopSession.addSessionAttribute("status", "completed");
67+
68+
CompletableFuture<Void> stopFuture = SessionRecorder.stop(stopSession);
69+
stopFuture.join(); // Wait for completion
70+
System.out.println("✅ Session recording stopped successfully");
71+
72+
} catch (Exception e) {
73+
System.err.println("❌ Failed to start session recording: " + e.getMessage());
74+
e.printStackTrace();
75+
return;
76+
}
77+
78+
} catch (Exception e) {
79+
System.err.println("❌ Failed to initialize SessionRecorder: " + e.getMessage());
80+
e.printStackTrace();
81+
}
82+
}
83+
84+
/**
85+
* Example of using continuous sessions
86+
*/
87+
public static void continuousSessionExample() {
88+
System.out.println("\n🔄 Continuous Session Example:");
89+
90+
try {
91+
// Initialize if not already done
92+
if (!SessionRecorder.isInitialized()) {
93+
SessionRecorderConfig config = new SessionRecorderConfig();
94+
config.setApiKey(Config.MULTIPLAYER_OTLP_KEY);
95+
config.setTraceIdGenerator(OpenTelemetry.getIdGenerator());
96+
SessionRecorder.init(config);
97+
}
98+
99+
// Create session for continuous recording
100+
Session session = new Session();
101+
session.setName("Continuous Debug Session");
102+
session.addTag("mode", "continuous");
103+
session.addTag("type", "debug");
104+
session.addSessionAttribute("mode", "continuous");
105+
106+
// Start continuous session
107+
CompletableFuture<Void> startFuture = SessionRecorder.start(SessionType.CONTINUOUS, session);
108+
startFuture.join();
109+
System.out.println("✅ Continuous session started");
110+
111+
// Simulate saving data multiple times
112+
for (int i = 1; i <= 3; i++) {
113+
Thread.sleep(1000); // Wait 1 second
114+
115+
Session saveData = new Session();
116+
saveData.setName("Save point " + i);
117+
saveData.addTag("type", "save-point");
118+
saveData.addSessionAttribute("iteration", String.valueOf(i));
119+
120+
CompletableFuture<Void> saveFuture = SessionRecorder.save(saveData);
121+
saveFuture.join();
122+
System.out.println("💾 Saved data point " + i);
123+
}
124+
125+
// Cancel the continuous session
126+
CompletableFuture<Void> cancelFuture = SessionRecorder.cancel();
127+
cancelFuture.join();
128+
System.out.println("✅ Continuous session cancelled");
129+
130+
} catch (Exception e) {
131+
System.err.println("❌ Continuous session error: " + e.getMessage());
132+
e.printStackTrace();
133+
}
134+
}
135+
136+
/**
137+
* Example of error handling and session cancellation
138+
*/
139+
public static void errorHandlingExample() {
140+
System.out.println("\n⚠️ Error Handling Example:");
141+
142+
try {
143+
// Initialize if not already done
144+
if (!SessionRecorder.isInitialized()) {
145+
SessionRecorderConfig config = new SessionRecorderConfig();
146+
config.setApiKey(Config.MULTIPLAYER_OTLP_KEY);
147+
config.setTraceIdGenerator(OpenTelemetry.getIdGenerator());
148+
SessionRecorder.init(config);
149+
}
150+
151+
// Start a session
152+
Session session = new Session();
153+
session.setName("Error Handling Test");
154+
session.addTag("type", "error-test");
155+
156+
CompletableFuture<Void> startFuture = SessionRecorder.start(SessionType.PLAIN, session);
157+
startFuture.join();
158+
System.out.println("✅ Session started for error handling test");
159+
160+
// Simulate an error condition
161+
boolean errorOccurred = true; // Simulate error
162+
163+
if (errorOccurred) {
164+
System.out.println("⚠️ Error occurred, cancelling session...");
165+
166+
try {
167+
CompletableFuture<Void> cancelFuture = SessionRecorder.cancel();
168+
cancelFuture.join();
169+
System.out.println("✅ Session cancelled due to error");
170+
} catch (Exception cancelError) {
171+
System.err.println("❌ Failed to cancel session: " + cancelError.getMessage());
172+
}
173+
}
174+
175+
} catch (Exception e) {
176+
System.err.println("❌ Error handling example failed: " + e.getMessage());
177+
e.printStackTrace();
178+
}
179+
}
180+
}

0 commit comments

Comments
 (0)