Add a sample of Golang gRPC client/server programs
This commit is contained in:
parent
027e1569e0
commit
124acba6db
6
demos/golang/grpc_pingpong/.gitignore
vendored
Normal file
6
demos/golang/grpc_pingpong/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
occlum_ping
|
||||
occlum_pong
|
||||
occlum_ping_instance/
|
||||
occlum_pong_instance/
|
||||
go.sum
|
||||
github.com/
|
20
demos/golang/grpc_pingpong/README.md
Normal file
20
demos/golang/grpc_pingpong/README.md
Normal file
@ -0,0 +1,20 @@
|
||||
# Use Golang and gRPC with Occlum
|
||||
|
||||
This project demonstrates how Occlum enables [Golang](https://golang.org) programs with [gRPC](google.golang.org/grpc) calls running in SGX enclaves. The client program invokes a gRPC call with a ping message, and receives a pong message sent by the server program.
|
||||
|
||||
Step 1: Build the Golang gRPC application using the Occlum Golang toolchain via
|
||||
```
|
||||
./prepare_ping_pong.sh
|
||||
```
|
||||
|
||||
Step 2: Run the gRPC server demo on Occlum via
|
||||
```
|
||||
./run_pong_on_occlum.sh
|
||||
```
|
||||
The gRPC server should now start to listen on port 8888 and serve incoming requests.
|
||||
|
||||
Step 3: Run the gRPC client demo on Occlum via
|
||||
```
|
||||
./run_ping_on_occlum.sh
|
||||
```
|
||||
After the reply message is received, the latency incurred during a gRPC call will be printed out.
|
9
demos/golang/grpc_pingpong/go.mod
Normal file
9
demos/golang/grpc_pingpong/go.mod
Normal file
@ -0,0 +1,9 @@
|
||||
module grpc_pingpong
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/golang/protobuf v1.4.1
|
||||
google.golang.org/grpc v1.33.0-dev
|
||||
google.golang.org/protobuf v1.25.0
|
||||
)
|
31
demos/golang/grpc_pingpong/ping.go
Normal file
31
demos/golang/grpc_pingpong/ping.go
Normal file
@ -0,0 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"grpc_pingpong/github.com/occlum/demos/grpc_pingpong/pingpong"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conn, err := grpc.Dial("localhost:8888", grpc.WithInsecure())
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to connect: %s\n", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
previousTime := time.Now()
|
||||
fmt.Printf("Ping: at %s\n", previousTime.Format("2006-01-02T15:04:05.999999999Z07:00"))
|
||||
client := pingpong.NewPingPongServiceClient(conn)
|
||||
response, err := client.PingPong(context.Background(), &pingpong.PingPongMesg{Ping: "Hello"})
|
||||
if err != nil {
|
||||
fmt.Printf("Error when calling PingPongHandler: %s\n", err)
|
||||
}
|
||||
fmt.Printf("Pong from server: %s (at %s)\n", response.Pong, response.Timestamp)
|
||||
currentTime := time.Now()
|
||||
fmt.Printf("End-to-End latency is: %f Seconds\n", currentTime.Sub(previousTime).Seconds())
|
||||
}
|
||||
|
13
demos/golang/grpc_pingpong/pingpong/pingpong.proto
Normal file
13
demos/golang/grpc_pingpong/pingpong/pingpong.proto
Normal file
@ -0,0 +1,13 @@
|
||||
syntax = "proto3";
|
||||
package pingpong;
|
||||
option go_package = "github.com/occlum/demos/grpc_pingpong/pingpong";
|
||||
|
||||
message PingPongMesg {
|
||||
string ping = 1;
|
||||
string pong = 2;
|
||||
string timestamp = 3;
|
||||
}
|
||||
|
||||
service PingPongService {
|
||||
rpc PingPong(PingPongMesg) returns (PingPongMesg) {}
|
||||
}
|
38
demos/golang/grpc_pingpong/pong.go
Normal file
38
demos/golang/grpc_pingpong/pong.go
Normal file
@ -0,0 +1,38 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"grpc_pingpong/github.com/occlum/demos/grpc_pingpong/pingpong"
|
||||
)
|
||||
|
||||
func PingPong(ctx context.Context, in *pingpong.PingPongMesg) (*pingpong.PingPongMesg, error) {
|
||||
currentTime := time.Now()
|
||||
fmt.Printf("Receiving Ping: %s (at %s)\n", in.Ping, currentTime.Format("2006-01-02T15:04:05.999999999Z07:00"))
|
||||
return &pingpong.PingPongMesg{Ping: in.Ping,
|
||||
Pong: fmt.Sprintf("Greetings from Pong! Ping Echoed: %s", in.Ping),
|
||||
Timestamp: currentTime.Format("2006-01-02T15:04:05.999999999Z07:00")}, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("grpc_pingpong server is waiting for service requests ...")
|
||||
|
||||
conn, err := net.Listen("tcp", "localhost:8888")
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to listen: %v\n", err)
|
||||
}
|
||||
|
||||
grpcServer := grpc.NewServer()
|
||||
|
||||
pingpong.RegisterPingPongServiceService(grpcServer, &pingpong.PingPongServiceService{PingPong: PingPong})
|
||||
|
||||
if err := grpcServer.Serve(conn); err != nil {
|
||||
fmt.Printf("Failed to serve: %s\n", err)
|
||||
}
|
||||
}
|
||||
|
56
demos/golang/grpc_pingpong/prepare_ping_pong.sh
Executable file
56
demos/golang/grpc_pingpong/prepare_ping_pong.sh
Executable file
@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
BLUE='\033[1;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
# sanity check
|
||||
FILE_SET="
|
||||
occlum_ping
|
||||
occlum_pong
|
||||
go.sum"
|
||||
for CURR_FILE in $FILE_SET
|
||||
do
|
||||
if [ -f "$CURR_FILE" ]; then
|
||||
rm $CURR_FILE
|
||||
fi
|
||||
done
|
||||
|
||||
DIR_SET="
|
||||
github.com
|
||||
occlum_ping_instance
|
||||
occlum_pong_instance"
|
||||
for CURR_DIR in $DIR_SET
|
||||
do
|
||||
if [ -d "$CURR_DIR" ]; then
|
||||
rm -fr $CURR_DIR
|
||||
fi
|
||||
done
|
||||
|
||||
# enable Go modules for package management
|
||||
export GO111MODULE=on
|
||||
|
||||
# update PATH so that the protoc compiler can find the plugin:
|
||||
export PATH="$PATH:$(go env GOPATH)/bin"
|
||||
|
||||
# assume that protoc is installed
|
||||
if ! type "protoc" > /dev/null 2>&1; then
|
||||
echo "Please install protoc"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# install protoc-gen-go and protoc-gen-go-grpc plugin
|
||||
if ! type "protoc-gen-go" > /dev/null 2>&1; then
|
||||
go get google.golang.org/protobuf/cmd/protoc-gen-go
|
||||
fi
|
||||
if ! type "protoc-gen-go-grpc" > /dev/null 2>&1; then
|
||||
go get google.golang.org/grpc/cmd/protoc-gen-go-grpc
|
||||
fi
|
||||
|
||||
# compiling pingpong gRPC .proto file
|
||||
export GOPRIVATE=github.com/occlum/demos/\*
|
||||
protoc --proto_path=pingpong --go-grpc_out=. --go_out=. pingpong/pingpong.proto
|
||||
|
||||
# prepare occlum images
|
||||
occlum-go build -o occlum_pong pong.go
|
||||
occlum-go build -o occlum_ping ping.go
|
35
demos/golang/grpc_pingpong/run_ping_on_occlum.sh
Executable file
35
demos/golang/grpc_pingpong/run_ping_on_occlum.sh
Executable file
@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
BLUE='\033[1;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
occlum_ping="./occlum_ping"
|
||||
|
||||
if [ ! -f $occlum_ping ];then
|
||||
echo "Error: cannot stat file '$occlum_ping'"
|
||||
echo "Please see README and build it using prepare_ping_pong.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Init Occlum Workspace
|
||||
rm -rf occlum_ping_instance && mkdir occlum_ping_instance
|
||||
cd occlum_ping_instance
|
||||
occlum init
|
||||
new_json="$(jq '.resource_limits.user_space_size = "2560MB" |
|
||||
.resource_limits.kernel_space_heap_size="320MB" |
|
||||
.resource_limits.kernel_space_stack_size="10MB" |
|
||||
.process.default_stack_size = "40MB" |
|
||||
.process.default_heap_size = "320MB" |
|
||||
.process.default_mmap_size = "960MB" ' Occlum.json)" && \
|
||||
echo "${new_json}" > Occlum.json
|
||||
|
||||
# 2. Copy program into Occlum Workspace and build
|
||||
cp ../occlum_ping image/bin
|
||||
mkdir image/etc/
|
||||
cp /etc/hosts image/etc/
|
||||
occlum build
|
||||
|
||||
# 3. Run the hello world sample
|
||||
echo -e "${BLUE}occlum run /bin/occlum_ping${NC}"
|
||||
time occlum run /bin/occlum_ping
|
35
demos/golang/grpc_pingpong/run_pong_on_occlum.sh
Executable file
35
demos/golang/grpc_pingpong/run_pong_on_occlum.sh
Executable file
@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
BLUE='\033[1;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
occlum_pong="./occlum_pong"
|
||||
|
||||
if [ ! -f $occlum_pong ];then
|
||||
echo "Error: cannot stat file '$occlum_pong'"
|
||||
echo "Please see README and build it using prepare_pong_pong.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Init Occlum Workspace
|
||||
rm -rf occlum_pong_instance && mkdir occlum_pong_instance
|
||||
cd occlum_pong_instance
|
||||
occlum init
|
||||
new_json="$(jq '.resource_limits.user_space_size = "2560MB" |
|
||||
.resource_limits.kernel_space_heap_size="320MB" |
|
||||
.resource_limits.kernel_space_stack_size="10MB" |
|
||||
.process.default_stack_size = "40MB" |
|
||||
.process.default_heap_size = "320MB" |
|
||||
.process.default_mmap_size = "960MB" ' Occlum.json)" && \
|
||||
echo "${new_json}" > Occlum.json
|
||||
|
||||
# 2. Copy program into Occlum Workspace and build
|
||||
cp ../occlum_pong image/bin
|
||||
mkdir image/etc/
|
||||
cp /etc/hosts image/etc/
|
||||
occlum build
|
||||
|
||||
# 3. Run the hello world sample
|
||||
echo -e "${BLUE}occlum run /bin/occlum_pong${NC}"
|
||||
time occlum run /bin/occlum_pong
|
Loading…
Reference in New Issue
Block a user