Skip to content

Commit

Permalink
Another pass readme (#152)
Browse files Browse the repository at this point in the history
* Improve examples readme

* Improve README and javadoc of CoreSerdes
  • Loading branch information
slinkydeveloper authored Nov 20, 2023
1 parent 4602ef0 commit 5b280e2
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 26 deletions.
62 changes: 37 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,16 @@ protobuf {
protoc { artifact = "com.google.protobuf:protoc:3.24.3" }

plugins {
// The Restate plugin depends on the gRPC generated code
id("grpc") { artifact = "io.grpc:protoc-gen-grpc-java:1.58.0" }
id("restate") { artifact = "dev.restate.sdk:protoc-gen-restate-java-blocking:1.0-SNAPSHOT:all@jar" }
}

generateProtoTasks {
all().forEach {
it.plugins {
id("grpc")
id("restate")
}
}
}
Expand Down Expand Up @@ -115,18 +118,19 @@ protobuf {
protoc { artifact = "com.google.protobuf:protoc:3.24.3" }

plugins {
// The gRPC Kotlin plugin depends on the gRPC generated code
id("grpc") { artifact = "io.grpc:protoc-gen-grpc-java:1.58.0" }
id("grpckt") { artifact = "io.grpc:protoc-gen-grpc-kotlin:1.4.0:jdk8@jar" }
}

generateProtoTasks {
all().forEach {
// We need both java and kotlin codegen(s) because the kotlin protobuf/grpc codegen depends on the java ones
it.plugins {
id("grpc")
id("grpckt")
}
it.builtins {
// The Kotlin codegen depends on the Java generated code
java {}
id("kotlin")
}
Expand Down Expand Up @@ -170,32 +174,23 @@ By using the Gradle or Maven plugin, the code is automatically re-generated on e
Implement the service in a new class, for example:

```java
public class Greeter extends GreeterGrpc.GreeterImplBase implements RestateBlockingService {
public class Greeter extends GreeterRestate.GreeterRestateImplBase {

private static final StateKey<Long> COUNT = StateKey.of("total", Long.class);
private static final StateKey<Long> COUNT = StateKey.of("total", CoreSerdes.LONG);

@Override
public void greet(GreetRequest request, StreamObserver<GreetResponse> responseObserver) {
RestateContext ctx = restateContext();

public GreetResponse greet(RestateContext ctx, GreetRequest request) {
long count = ctx.get(COUNT).orElse(0L);
ctx.set(COUNT, count + 1);

responseObserver.onNext(
GreetResponse.newBuilder()
.setMessage(String.format("Hello %s for the %d time!", request.getName(), count))
.build());
responseObserver.onCompleted();
return GreetResponse.newBuilder()
.setMessage(String.format("Hello %s for the %d time!", request.getName(), count))
.build();
}
}
```

To serialize the state, you need a state serializer/deserializer.
To use [Jackson Databind](https://github.com/FasterXML/jackson), add the dependency [`sdk-serde-jackson`](sdk-serde-jackson). For example, in Gradle:

```
implementation("dev.restate.sdk:sdk-serde-jackson:1.0-SNAPSHOT")
```
If you want to use POJOs for state, check [how to use Jackson](#state-serde-using-jackson).

### Implement the service (Kotlin)

Expand All @@ -207,7 +202,7 @@ class Greeter :
GreeterGrpcKt.GreeterCoroutineImplBase(Dispatchers.Unconfined),
RestateCoroutineService {
companion object {
private val COUNT = StateKey.of("total", Long::class.java)
private val COUNT = StateKey.of("total", CoreSerdes.LONG)
}

override suspend fun greet(request: GreetRequest): GreetResponse {
Expand All @@ -219,12 +214,7 @@ class Greeter :
}
```

To serialize the state, you need a state serializer/deserializer.
To use [Jackson Databind](https://github.com/FasterXML/jackson), add the dependency [`sdk-serde-jackson`](sdk-serde-jackson). For example, in Gradle:

```
implementation("dev.restate.sdk:sdk-serde-jackson:1.0-SNAPSHOT")
```
If you want to use POJOs for state, check [how to use Jackson](#state-serde-using-jackson).

### Deploy the service (HTTP Server)

Expand Down Expand Up @@ -316,6 +306,22 @@ You can now upload the generated Jar in AWS Lambda, and configure `dev.restate.s

### Additional setup

#### State ser/de using Jackson

State ser/de is defined by the interface `Serde`. If you want to use [Jackson Databind](https://github.com/FasterXML/jackson) to ser/de POJOs to JSON, add the dependency [`sdk-serde-jackson`](sdk-serde-jackson).

For example, in Gradle:

```
implementation("dev.restate.sdk:sdk-serde-jackson:1.0-SNAPSHOT")
```

And then use `JacksonSerdes`:

```java
private static final StateKey<Person> PERSON = StateKey.of("person", JacksonSerdes.of(Person.class));
```

#### Logging

The SDK uses log4j2 as logging facade. To enable logging, add the `log4j2` implementation to the dependencies:
Expand All @@ -334,7 +340,7 @@ status = warn
appender.console.type = Console
appender.console.name = consoleLogger
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} [%tn] %-5p %c{1}:%L - %m%n
appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %notEmpty{[%X{restateServiceMethod}]}%notEmpty{[%X{restateInvocationId}]} %c - %m%n
# Restate logs to debug level
logger.app.name = dev.restate
Expand All @@ -347,6 +353,12 @@ rootLogger.level = info
rootLogger.appenderRef.stdout.ref = consoleLogger
```

The SDK injects the following additional metadata to the logging context that can be used for filtering as well:

* `restateServiceMethod`: service and method, e.g. `counter.Counter/Add`.
* `restateInvocationId`: Invocation identifier, to be used in Restate observability tools. See https://docs.restate.dev/services/invocation#invocation-identifier.
* `restateInvocationStatus`: Invocation status, can be `WAITING_START`, `REPLAYING`, `PROCESSING`, `CLOSED`.

#### Tracing with OpenTelemetry

The SDK can generate additional tracing information on top of what Restate already publishes. See https://docs.restate.dev/restate/tracing to configure Restate tracing.
Expand Down
8 changes: 7 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

This directory contains different examples of the SDK features.

For a sample project configuration, check out the templates in https://github.com/restatedev/examples/tree/main/jvm.
For a sample project configuration and more elaborated examples, check out the templates in https://github.com/restatedev/examples/tree/main/jvm.

Available examples:

* [`Counter`](src/main/java/dev/restate/sdk/examples/Counter.java): Shows a simple service using state primitives.
* [`VanillaGrpcCounter`](src/main/java/dev/restate/sdk/examples/VanillaGrpcCounter.java): Same as `Counter` but using the vanilla gRPC code generator output.
* [`CounterKt`](src/main/kotlin/dev/restate/sdk/examples/CounterKt.kt): Same as `Counter` but using Kotlin.

## Package the examples for Lambda

Expand Down
5 changes: 5 additions & 0 deletions sdk-core/src/main/java/dev/restate/sdk/core/CoreSerdes.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
import java.util.Objects;
import javax.annotation.Nullable;

/**
* Collection of common serializers/deserializers.
*
* <p>To ser/de POJOs using JSON, you can use the module {@code sdk-serde-jackson}.
*/
public abstract class CoreSerdes {

private CoreSerdes() {}
Expand Down

0 comments on commit 5b280e2

Please sign in to comment.