| Jens Geyer | 0853ab6 | 2013-12-17 21:38:44 +0100 | [diff] [blame] | 1 | Thrift Go Software Library |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 2 | |
| 3 | License |
| 4 | ======= |
| 5 | |
| 6 | Licensed to the Apache Software Foundation (ASF) under one |
| 7 | or more contributor license agreements. See the NOTICE file |
| 8 | distributed with this work for additional information |
| 9 | regarding copyright ownership. The ASF licenses this file |
| 10 | to you under the Apache License, Version 2.0 (the |
| 11 | "License"); you may not use this file except in compliance |
| 12 | with the License. You may obtain a copy of the License at |
| 13 | |
| 14 | http://www.apache.org/licenses/LICENSE-2.0 |
| 15 | |
| 16 | Unless required by applicable law or agreed to in writing, |
| 17 | software distributed under the License is distributed on an |
| 18 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 19 | KIND, either express or implied. See the License for the |
| 20 | specific language governing permissions and limitations |
| 21 | under the License. |
| 22 | |
| Jens Geyer | 0853ab6 | 2013-12-17 21:38:44 +0100 | [diff] [blame] | 23 | |
| Yuxuan 'fishy' Wang | a265236 | 2021-08-04 09:07:53 -0700 | [diff] [blame] | 24 | Suppored Go releases |
| 25 | ==================== |
| 26 | |
| 27 | Following the |
| 28 | [official Go release policy](https://golang.org/doc/devel/release#policy), |
| 29 | we support the latest two Go releases at the time of the Thrift release. |
| 30 | |
| 31 | For example, at the time of Thrift v0.14.0 release, |
| 32 | the latest two Go releases are go1.15 and go1.14, |
| 33 | and those are the two Go releases supported by Thrift v0.14.* |
| 34 | (including v0.14.1 and v0.14.2 patch releases). |
| 35 | |
| 36 | Because of Go's backward compatibility guarantee, |
| 37 | older Thrift libraries usually works with newer Go releases |
| 38 | (e.g. Thrift v0.14.* works with go1.16, although it's not officially supported), |
| 39 | but newer Thrift releases might use new APIs introduced in Go releases and no |
| 40 | longer work with older Go releases. |
| 41 | For example, Thrift v0.14.0 used APIs introduced in go1.13, |
| 42 | and as a result no longer works on go1.12. |
| 43 | |
| 44 | |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 45 | Using Thrift with Go |
| 46 | ==================== |
| 47 | |
| Yuxuan 'fishy' Wang | 68c0272 | 2021-07-26 08:59:01 -0700 | [diff] [blame] | 48 | Thrift supports the currently officially supported Go releases (the latest 2). |
| John Boiles | 5785279 | 2018-01-05 14:37:05 -0800 | [diff] [blame] | 49 | |
| Yuxuan 'fishy' Wang | 68c0272 | 2021-07-26 08:59:01 -0700 | [diff] [blame] | 50 | After initializing the go modules file in your project, use the following |
| 51 | command to add the most recent version of the package: |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 52 | |
| Yuxuan 'fishy' Wang | 68c0272 | 2021-07-26 08:59:01 -0700 | [diff] [blame] | 53 | $ go get github.com/apache/thrift |
| Jens Geyer | 0853ab6 | 2013-12-17 21:38:44 +0100 | [diff] [blame] | 54 | |
| 55 | |
| 56 | A note about optional fields |
| 57 | ============================ |
| 58 | |
| 59 | The thrift-to-Go compiler tries to represent thrift IDL structs as Go structs. |
| 60 | We must be able to distinguish between optional fields that are set to their |
| 61 | default value and optional values which are actually unset, so the generated |
| 62 | code represents optional fields via pointers. |
| 63 | |
| 64 | This is generally intuitive and works well much of the time, but Go does not |
| 65 | have a syntax for creating a pointer to a constant in a single expression. That |
| 66 | is, given a struct like |
| 67 | |
| 68 | struct SomeIDLType { |
| 69 | OptionalField *int32 |
| 70 | } |
| 71 | |
| 72 | , the following will not compile: |
| 73 | |
| 74 | x := &SomeIDLType{ |
| 75 | OptionalField: &(3), |
| 76 | } |
| 77 | |
| 78 | (Nor is there any other syntax that's built in to the language) |
| 79 | |
| 80 | As such, we provide some helpers that do just this under lib/go/thrift/. E.g., |
| 81 | |
| 82 | x := &SomeIDLType{ |
| 83 | OptionalField: thrift.Int32Ptr(3), |
| 84 | } |
| 85 | |
| 86 | And so on. The code generator also creates analogous helpers for user-defined |
| 87 | typedefs and enums. |
| Richard Artoul | c3a3f65 | 2016-07-22 14:26:53 -0700 | [diff] [blame] | 88 | |
| 89 | Adding custom tags to generated Thrift structs |
| 90 | ============================================== |
| 91 | |
| 92 | You can add tags to the auto-generated thrift structs using the following format: |
| 93 | |
| 94 | struct foo { |
| 95 | 1: required string Bar (go.tag = "some_tag:\"some_tag_value\"") |
| 96 | } |
| 97 | |
| 98 | which will generate: |
| 99 | |
| 100 | type Foo struct { |
| 101 | Bar string `thrift:"bar,1,required" some_tag:"some_tag_value"` |
| 102 | } |
| Yuxuan 'fishy' Wang | 4db7a0a | 2020-06-27 10:13:34 -0700 | [diff] [blame] | 103 | |
| 104 | A note about server handler implementations |
| 105 | =========================================== |
| 106 | |
| 107 | The context object passed into the server handler function will be canceled when |
| 108 | the client closes the connection (this is a best effort check, not a guarantee |
| 109 | -- there's no guarantee that the context object is always canceled when client |
| 110 | closes the connection, but when it's canceled you can always assume the client |
| Yuxuan 'fishy' Wang | 0e872c8 | 2023-08-09 15:06:37 -0700 | [diff] [blame] | 111 | closed the connection). The cause of the cancellation (via `context.Cause(ctx)`) |
| 112 | would also be set to `thrift.ErrAbandonRequest`. |
| 113 | |
| 114 | When implementing Go Thrift server, you can take advantage of that to abandon |
| 115 | requests that's no longer needed by returning `thrift.ErrAbandonRequest`: |
| Yuxuan 'fishy' Wang | 4db7a0a | 2020-06-27 10:13:34 -0700 | [diff] [blame] | 116 | |
| 117 | func MyEndpoint(ctx context.Context, req *thriftRequestType) (*thriftResponseType, error) { |
| 118 | ... |
| 119 | if ctx.Err() == context.Canceled { |
| 120 | return nil, thrift.ErrAbandonRequest |
| Yuxuan 'fishy' Wang | 0e872c8 | 2023-08-09 15:06:37 -0700 | [diff] [blame] | 121 | // Or just return ctx.Err(), compiler generated processor code will |
| 122 | // handle it for you automatically: |
| 123 | // return nil, ctx.Err() |
| Yuxuan 'fishy' Wang | 4db7a0a | 2020-06-27 10:13:34 -0700 | [diff] [blame] | 124 | } |
| 125 | ... |
| 126 | } |
| 127 | |
| 128 | This feature would add roughly 1 millisecond of latency overhead to the server |
| 129 | handlers (along with roughly 2 goroutines per request). |
| 130 | If that is unacceptable, it can be disabled by having this line early in your |
| 131 | main function: |
| 132 | |
| 133 | thrift.ServerConnectivityCheckInterval = 0 |
| 134 | |
| Yuxuan 'fishy' Wang | daf6209 | 2020-10-07 16:28:38 -0700 | [diff] [blame] | 135 | Please be advised that due to a |
| 136 | [Go runtime bug](https://github.com/golang/go/issues/27707), currently |
| 137 | if this interval is set to a value too low (for example, 1ms), it might cause |
| 138 | excessive cpu overhead. |
| 139 | |
| Yuxuan 'fishy' Wang | 4db7a0a | 2020-06-27 10:13:34 -0700 | [diff] [blame] | 140 | This feature is also only enabled on non-oneway endpoints. |
| 郑桐 | 2fa907e | 2022-01-04 18:20:24 +0800 | [diff] [blame] | 141 | |
| 142 | A note about server stop implementations |
| 143 | ======================================== |
| 144 | |
| 145 | [TSimpleServer.Stop](https://pkg.go.dev/github.com/apache/thrift/lib/go/thrift#TSimpleServer.Stop) will wait for all client connections to be closed after |
| 146 | the last received request to be handled, as the time spent by Stop |
| 147 | may sometimes be too long: |
| 148 | * When socket timeout is not set, server might be hanged before all active |
| 149 | clients to finish handling the last received request. |
| 150 | * When the socket timeout is too long (e.g one hour), server will |
| 151 | hang for that duration before all active clients to finish handling the |
| 152 | last received request. |
| 153 | |
| 154 | To prevent Stop from hanging for too long, you can set |
| 155 | thrift.ServerStopTimeout in your main or init function: |
| 156 | |
| 157 | thrift.ServerStopTimeout = <max_duration_to_stop> |
| 158 | |
| 159 | If it's set to <=0, the feature will be disabled (by default), and server |
| 160 | will wait for all the client connections to be closed gracefully with |
| 161 | zero err time. Otherwise, the stop will wait for all the client |
| 162 | connections to be closed gracefully util thrift.ServerStopTimeout is |
| 163 | reached, and client connections that are not closed after thrift.ServerStopTimeout |
| Yuxuan 'fishy' Wang | 0e872c8 | 2023-08-09 15:06:37 -0700 | [diff] [blame] | 164 | will be closed abruptly which may cause some client errors. |