Skip to content

Commit

Permalink
Isolate gRPC code (#195)
Browse files Browse the repository at this point in the history
* Add InvocationId to Syscalls
* Rename GrpcContextDataProvider to RestateContextDataProvider
* Add helper method to get poll input stream entry
* Rename RestateGrpcServer to RestateEndpoint
* Introduce RpcHandler. This is the well defined interface we can target for code-generation
* Add ability to register close callback on state machine, to get notified when the state machine is closed.
* Refactor existing gRPC adapter code, encapsulating it into GrpcUnaryRpcHandler.
Use the GrpcUnaryRpcHandler in RestateEndpoint
  • Loading branch information
slinkydeveloper authored Jan 30, 2024
1 parent f27c278 commit 095018a
Show file tree
Hide file tree
Showing 21 changed files with 726 additions and 701 deletions.
184 changes: 92 additions & 92 deletions gradlew.bat
Original file line number Diff line number Diff line change
@@ -1,92 +1,92 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem

@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto execute

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar


@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*

:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem

@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto execute

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar


@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*

:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import com.google.protobuf.ByteString;
import com.google.protobuf.MessageLite;
import dev.restate.sdk.common.InvocationId;
import dev.restate.sdk.common.TerminalException;
import io.grpc.Context;
import io.grpc.MethodDescriptor;
Expand Down Expand Up @@ -41,6 +42,8 @@ static Syscalls current() {
+ Thread.currentThread().getName());
}

InvocationId invocationId();

/**
* @return true if it's inside a side effect block.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// Copyright (c) 2023 - Restate Software, Inc., Restate GmbH
//
// This file is part of the Restate Java SDK,
// which is released under the MIT license.
//
// You can find a copy of the license in file LICENSE in the root
// directory of this repository or package, or at
// https://github.com/restatedev/sdk-java/blob/main/LICENSE
package dev.restate.sdk.core;

import com.google.protobuf.ByteString;
import com.google.protobuf.MessageLite;
import dev.restate.sdk.common.InvocationId;
import dev.restate.sdk.common.TerminalException;
import dev.restate.sdk.common.syscalls.DeferredResult;
import dev.restate.sdk.common.syscalls.EnterSideEffectSyscallCallback;
import dev.restate.sdk.common.syscalls.ExitSideEffectSyscallCallback;
import dev.restate.sdk.common.syscalls.SyscallCallback;
import io.grpc.MethodDescriptor;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.function.Function;

class ExecutorSwitchingSyscalls implements SyscallsInternal {

private final SyscallsInternal syscalls;
private final Executor syscallsExecutor;

ExecutorSwitchingSyscalls(SyscallsInternal syscalls, Executor syscallsExecutor) {
this.syscalls = syscalls;
this.syscallsExecutor = syscallsExecutor;
}

@Override
public <T extends MessageLite> void pollInput(
Function<ByteString, T> mapper, SyscallCallback<DeferredResult<T>> callback) {
syscallsExecutor.execute(() -> syscalls.pollInput(mapper, callback));
}

@Override
public <T extends MessageLite> void writeOutput(T value, SyscallCallback<Void> callback) {
syscallsExecutor.execute(() -> syscalls.writeOutput(value, callback));
}

@Override
public void writeOutput(TerminalException throwable, SyscallCallback<Void> callback) {
syscallsExecutor.execute(() -> syscalls.writeOutput(throwable, callback));
}

@Override
public void get(String name, SyscallCallback<DeferredResult<ByteString>> callback) {
syscallsExecutor.execute(() -> syscalls.get(name, callback));
}

@Override
public void clear(String name, SyscallCallback<Void> callback) {
syscallsExecutor.execute(() -> syscalls.clear(name, callback));
}

@Override
public void set(String name, ByteString value, SyscallCallback<Void> callback) {
syscallsExecutor.execute(() -> syscalls.set(name, value, callback));
}

@Override
public void sleep(Duration duration, SyscallCallback<DeferredResult<Void>> callback) {
syscallsExecutor.execute(() -> syscalls.sleep(duration, callback));
}

@Override
public <T, R> void call(
MethodDescriptor<T, R> methodDescriptor,
T parameter,
SyscallCallback<DeferredResult<R>> callback) {
syscallsExecutor.execute(() -> syscalls.call(methodDescriptor, parameter, callback));
}

@Override
public <T> void backgroundCall(
MethodDescriptor<T, ?> methodDescriptor,
T parameter,
Duration delay,
SyscallCallback<Void> requestCallback) {
syscallsExecutor.execute(
() -> syscalls.backgroundCall(methodDescriptor, parameter, delay, requestCallback));
}

@Override
public void enterSideEffectBlock(EnterSideEffectSyscallCallback callback) {
syscallsExecutor.execute(() -> syscalls.enterSideEffectBlock(callback));
}

@Override
public void exitSideEffectBlock(ByteString toWrite, ExitSideEffectSyscallCallback callback) {
syscallsExecutor.execute(() -> syscalls.exitSideEffectBlock(toWrite, callback));
}

@Override
public void exitSideEffectBlockWithTerminalException(
TerminalException toWrite, ExitSideEffectSyscallCallback callback) {
syscallsExecutor.execute(
() -> syscalls.exitSideEffectBlockWithTerminalException(toWrite, callback));
}

@Override
public void awakeable(SyscallCallback<Map.Entry<String, DeferredResult<ByteString>>> callback) {
syscallsExecutor.execute(() -> syscalls.awakeable(callback));
}

@Override
public void resolveAwakeable(
String id, ByteString payload, SyscallCallback<Void> requestCallback) {
syscallsExecutor.execute(() -> syscalls.resolveAwakeable(id, payload, requestCallback));
}

@Override
public void rejectAwakeable(String id, String reason, SyscallCallback<Void> requestCallback) {
syscallsExecutor.execute(() -> syscalls.rejectAwakeable(id, reason, requestCallback));
}

@Override
public <T> void resolveDeferred(
DeferredResult<T> deferredToResolve, SyscallCallback<Void> callback) {
syscallsExecutor.execute(() -> syscalls.resolveDeferred(deferredToResolve, callback));
}

@Override
public String getFullyQualifiedMethodName() {
// We can read this from another thread
return syscalls.getFullyQualifiedMethodName();
}

@Override
public InvocationState getInvocationState() {
// We can read this from another thread
return syscalls.getInvocationState();
}

@Override
public InvocationId invocationId() {
// This is immutable once set
return syscalls.invocationId();
}

@Override
public boolean isInsideSideEffect() {
// We can read this from another thread
return syscalls.isInsideSideEffect();
}

@Override
public void close() {
syscallsExecutor.execute(syscalls::close);
}

@Override
public void fail(Throwable cause) {
syscallsExecutor.execute(() -> syscalls.fail(cause));
}
}
Loading

0 comments on commit 095018a

Please sign in to comment.