Skip to content

Commit eb66f1b

Browse files
committed
examples: add FastHTTP feature example
1 parent 7fc8689 commit eb66f1b

10 files changed

Lines changed: 354 additions & 12 deletions

File tree

examples/features/config/client/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func main() {
3737
// Send request.
3838
rsp, err := clientProxy.SayHello(ctx, req)
3939
if err != nil {
40-
fmt.Println("Say hi err:%v", err)
40+
fmt.Printf("Say hi err:%v\n", err)
4141
return
4242
}
4343
fmt.Printf("Get msg: %s\n", rsp.GetMsg())
@@ -54,7 +54,7 @@ func main() {
5454
// Send request.
5555
rsp, err = clientProxy.SayHello(ctx, req)
5656
if err != nil {
57-
fmt.Println("Say hi err:%v", err)
57+
fmt.Printf("Say hi err:%v\n", err)
5858
return
5959
}
6060
fmt.Printf("Get msg: %s\n", rsp.GetMsg())
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# FastHTTP
2+
3+
This example demonstrates a standard HTTP service implemented with FastHTTP in
4+
tRPC-Go.
5+
6+
## Usage
7+
8+
* Start server.
9+
10+
```shell
11+
$ go run server/main.go -conf server/trpc_go.yaml
12+
```
13+
14+
* Run client.
15+
16+
```shell
17+
$ go run client/main.go
18+
```
19+
20+
* Or send a curl request.
21+
22+
```shell
23+
$ curl -X POST -H "hello: curl" http://127.0.0.1:8080/v1/hello
24+
```
25+
26+
The server replies with the request path, the `hello` header, and the HTTP
27+
method used by the request.
28+
29+
## Explanation
30+
31+
This example uses `fasthttp_no_protocol` on the server side. The client shows
32+
two calling styles:
33+
34+
* `NewFastHTTPClientProxy`, which keeps tRPC client options such as target
35+
routing and serialization options.
36+
* `NewFastHTTPClient`, which exposes a direct FastHTTP-style client.
37+
38+
For more information, see [FastHTTP transport](/http/README.md#fasthttp-transport).
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//
2+
//
3+
// Tencent is pleased to support the open source community by making tRPC available.
4+
//
5+
// Copyright (C) 2023 Tencent.
6+
// All rights reserved.
7+
//
8+
// If you have downloaded a copy of the tRPC source code from Tencent,
9+
// please note that tRPC source code is licensed under the Apache 2.0 License,
10+
// A copy of the Apache 2.0 License is included in this file.
11+
//
12+
//
13+
14+
// Package main is the client main package for FastHTTP demo.
15+
package main
16+
17+
import (
18+
"context"
19+
20+
"github.com/valyala/fasthttp"
21+
22+
"trpc.group/trpc-go/trpc-go/client"
23+
"trpc.group/trpc-go/trpc-go/codec"
24+
thttp "trpc.group/trpc-go/trpc-go/http"
25+
"trpc.group/trpc-go/trpc-go/log"
26+
)
27+
28+
func main() {
29+
callWithFastHTTPClientProxy()
30+
callWithFastHTTPClient()
31+
}
32+
33+
func callWithFastHTTPClientProxy() {
34+
proxy := thttp.NewFastHTTPClientProxy(
35+
"trpc.app.server.fasthttp",
36+
client.WithCurrentSerializationType(codec.SerializationTypeNoop),
37+
client.WithTarget("ip://127.0.0.1:8080"),
38+
)
39+
40+
reqHead := &thttp.FastHTTPClientReqHeader{
41+
Method: fasthttp.MethodPost,
42+
DecorateRequest: func(req *fasthttp.Request) *fasthttp.Request {
43+
req.Header.Set("hello", "proxy")
44+
return req
45+
},
46+
}
47+
rspHead := &thttp.FastHTTPClientRspHeader{}
48+
req := &codec.Body{Data: []byte("Hello, FastHTTP proxy!")}
49+
rsp := &codec.Body{}
50+
51+
if err := proxy.Post(context.Background(), "/v1/hello", req, rsp,
52+
client.WithReqHead(reqHead),
53+
client.WithRspHead(rspHead),
54+
); err != nil {
55+
log.Warnf("FastHTTPClientProxy request failed: %v", err)
56+
return
57+
}
58+
log.Infof("FastHTTPClientProxy response: %q, reply header: %q",
59+
rsp.Data, rspHead.Response.Header.Peek("reply"))
60+
}
61+
62+
func callWithFastHTTPClient() {
63+
fc := thttp.NewFastHTTPClient("trpc.app.server.fasthttp")
64+
65+
req := fasthttp.AcquireRequest()
66+
rsp := fasthttp.AcquireResponse()
67+
defer fasthttp.ReleaseRequest(req)
68+
defer fasthttp.ReleaseResponse(rsp)
69+
70+
req.Header.SetMethod(fasthttp.MethodGet)
71+
req.Header.Set("hello", "client")
72+
req.SetRequestURI("http://127.0.0.1:8080/v1/hello")
73+
74+
if err := fc.Do(req, rsp); err != nil {
75+
log.Warnf("FastHTTPClient request failed: %v", err)
76+
return
77+
}
78+
log.Infof("FastHTTPClient response: %q, reply header: %q",
79+
rsp.Body(), rsp.Header.Peek("reply"))
80+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//
2+
//
3+
// Tencent is pleased to support the open source community by making tRPC available.
4+
//
5+
// Copyright (C) 2023 Tencent.
6+
// All rights reserved.
7+
//
8+
// If you have downloaded a copy of the tRPC source code from Tencent,
9+
// please note that tRPC source code is licensed under the Apache 2.0 License,
10+
// A copy of the Apache 2.0 License is included in this file.
11+
//
12+
//
13+
14+
// Package main is the server main package for FastHTTP demo.
15+
package main
16+
17+
import (
18+
"fmt"
19+
20+
"github.com/valyala/fasthttp"
21+
22+
trpc "trpc.group/trpc-go/trpc-go"
23+
thttp "trpc.group/trpc-go/trpc-go/http"
24+
)
25+
26+
func main() {
27+
s := trpc.NewServer()
28+
29+
thttp.FastHTTPHandleFunc("/v1/hello", func(ctx *fasthttp.RequestCtx) {
30+
ctx.Response.Header.SetContentType("text/plain")
31+
ctx.Response.Header.Set("reply", "response head")
32+
ctx.SetStatusCode(fasthttp.StatusOK)
33+
ctx.WriteString(string(ctx.Path()) + ", " + string(ctx.Request.Header.Peek("hello")))
34+
if string(ctx.Method()) == fasthttp.MethodPost {
35+
ctx.WriteString("[POST]")
36+
}
37+
})
38+
39+
thttp.RegisterNoProtocolService(s.Service("trpc.app.server.fasthttp"))
40+
41+
if err := s.Serve(); err != nil {
42+
fmt.Println(err)
43+
}
44+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
global:
2+
namespace: development
3+
env_name: test
4+
5+
server:
6+
service:
7+
- name: trpc.app.server.fasthttp
8+
ip: 127.0.0.1
9+
port: 8080
10+
network: tcp
11+
protocol: fasthttp_no_protocol
12+
timeout: 1000
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Precool
2+
3+
This example demonstrates how to register a precool check for a service and how
4+
to query the precool status through the admin API.
5+
6+
## Usage
7+
8+
* Start server.
9+
10+
```shell
11+
$ go run server/main.go -conf server/trpc_go.yaml
12+
```
13+
14+
The server simulates three startup checks:
15+
16+
1. database connection
17+
2. cache warmup
18+
3. configuration loading
19+
20+
* Check process-level precool status.
21+
22+
```shell
23+
$ curl http://127.0.0.1:11014/cmds/is_precool/
24+
```
25+
26+
* Check service-level precool status.
27+
28+
```shell
29+
$ curl http://127.0.0.1:11014/cmds/is_precool/trpc.examples.precool.Precool
30+
```
31+
32+
Possible `is_precool` values are:
33+
34+
* `proc_success`: precool completed successfully
35+
* `proc_failure`: precool failed
36+
* `proc_ongoing`: precool is still in progress
37+
* `unknown`: service not registered or status unknown
38+
39+
## Explanation
40+
41+
The example registers a service-level precool strategy with
42+
`RegisterServicePrecool`. The strategy returns:
43+
44+
* `precool.Failure` before the first required dependency is ready
45+
* `precool.Ongoing` while later startup checks are still running
46+
* `precool.Success` when all startup checks have completed
47+
48+
This lets external readiness probes distinguish between failed startup, startup
49+
still in progress, and fully ready services.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//
2+
//
3+
// Tencent is pleased to support the open source community by making tRPC available.
4+
//
5+
// Copyright (C) 2023 Tencent.
6+
// All rights reserved.
7+
//
8+
// If you have downloaded a copy of the tRPC source code from Tencent,
9+
// please note that tRPC source code is licensed under the Apache 2.0 License,
10+
// A copy of the Apache 2.0 License is included in this file.
11+
//
12+
//
13+
14+
// Package main is the server main package for precool demo.
15+
package main
16+
17+
import (
18+
"fmt"
19+
"time"
20+
21+
trpc "trpc.group/trpc-go/trpc-go"
22+
"trpc.group/trpc-go/trpc-go/examples/features/common"
23+
"trpc.group/trpc-go/trpc-go/precool"
24+
pb "trpc.group/trpc-go/trpc-go/testdata/trpc/helloworld"
25+
)
26+
27+
type precoolChecker struct {
28+
dbReady bool
29+
cacheReady bool
30+
configReady bool
31+
}
32+
33+
func (pc *precoolChecker) CheckPrecool() precool.Status {
34+
if !pc.dbReady {
35+
return precool.Failure
36+
}
37+
if !pc.cacheReady || !pc.configReady {
38+
return precool.Ongoing
39+
}
40+
return precool.Success
41+
}
42+
43+
func main() {
44+
s := trpc.NewServer()
45+
checker := &precoolChecker{}
46+
47+
if err := s.RegisterServicePrecool("trpc.examples.precool.Precool", checker.CheckPrecool); err != nil {
48+
panic("register precool strategy: " + err.Error())
49+
}
50+
51+
go func() {
52+
fmt.Println("Starting precool process...")
53+
54+
time.Sleep(2 * time.Second)
55+
checker.dbReady = true
56+
fmt.Println("Database connection ready")
57+
58+
time.Sleep(3 * time.Second)
59+
checker.cacheReady = true
60+
fmt.Println("Cache warmup completed")
61+
62+
time.Sleep(1 * time.Second)
63+
checker.configReady = true
64+
fmt.Println("Configuration loaded")
65+
fmt.Println("Precool process completed successfully")
66+
}()
67+
68+
pb.RegisterGreeterService(s, &common.GreeterServerImpl{})
69+
70+
fmt.Println("Server starting with precool detection enabled...")
71+
fmt.Println("Check process status: curl http://127.0.0.1:11014/cmds/is_precool/")
72+
fmt.Println("Check service status: curl http://127.0.0.1:11014/cmds/is_precool/trpc.examples.precool.Precool")
73+
74+
if err := s.Serve(); err != nil {
75+
fmt.Println(err)
76+
}
77+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
global:
2+
namespace: Development
3+
4+
server:
5+
app: app
6+
server: server
7+
close_wait_time: 1000
8+
max_close_wait_time: 2000
9+
admin:
10+
ip: 127.0.0.1
11+
port: 11014
12+
read_timeout: 3000
13+
write_timeout: 60000
14+
service:
15+
- name: trpc.examples.precool.Precool
16+
protocol: trpc
17+
network: tcp
18+
address: "127.0.0.1:8000"
19+
timeout: 1000
20+
21+
client:
22+
timeout: 1000
23+
namespace: Development
24+
service:
25+
- name: trpc.examples.precool.Precool
26+
target: "ip://127.0.0.1:8000"
27+
protocol: trpc

examples/go.mod

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ replace trpc.group/trpc-go/trpc-go => ../
66

77
require (
88
github.com/golang/protobuf v1.5.2
9+
github.com/valyala/fasthttp v1.43.0
910
google.golang.org/protobuf v1.33.0
1011
trpc.group/trpc-go/trpc-go v0.0.0-00010101000000-000000000000
1112
trpc.group/trpc/trpc-protocol/pb/go/trpc v1.0.0
@@ -22,24 +23,27 @@ require (
2223
github.com/hashicorp/errwrap v1.0.0 // indirect
2324
github.com/hashicorp/go-multierror v1.1.1 // indirect
2425
github.com/json-iterator/go v1.1.12 // indirect
26+
github.com/kavu/go_reuseport v1.5.0 // indirect
2527
github.com/klauspost/compress v1.15.9 // indirect
2628
github.com/lestrrat-go/strftime v1.0.6 // indirect
2729
github.com/mitchellh/mapstructure v1.5.0 // indirect
2830
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
2931
github.com/modern-go/reflect2 v1.0.2 // indirect
3032
github.com/panjf2000/ants/v2 v2.4.6 // indirect
33+
github.com/pierrec/lz4/v4 v4.1.21 // indirect
3134
github.com/pkg/errors v0.9.1 // indirect
35+
github.com/r3labs/sse/v2 v2.10.0 // indirect
3236
github.com/spf13/cast v1.3.1 // indirect
3337
github.com/valyala/bytebufferpool v1.0.0 // indirect
34-
github.com/valyala/fasthttp v1.43.0 // indirect
35-
go.uber.org/atomic v1.9.0 // indirect
38+
go.uber.org/atomic v1.11.0 // indirect
3639
go.uber.org/automaxprocs v1.3.0 // indirect
3740
go.uber.org/multierr v1.6.0 // indirect
3841
go.uber.org/zap v1.24.0 // indirect
3942
golang.org/x/net v0.17.0 // indirect
4043
golang.org/x/sync v0.1.0 // indirect
41-
golang.org/x/sys v0.13.0 // indirect
44+
golang.org/x/sys v0.21.0 // indirect
4245
golang.org/x/text v0.13.0 // indirect
46+
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
4347
gopkg.in/yaml.v3 v3.0.1 // indirect
44-
trpc.group/trpc-go/tnet v1.0.1 // indirect
48+
trpc.group/trpc-go/tnet v1.1.0 // indirect
4549
)

0 commit comments

Comments
 (0)