158 lines
5.7 KiB
Markdown
158 lines
5.7 KiB
Markdown
Thrift Go Software Library
|
|
|
|
License
|
|
=======
|
|
|
|
Licensed to the Apache Software Foundation (ASF) under one
|
|
or more contributor license agreements. See the NOTICE file
|
|
distributed with this work for additional information
|
|
regarding copyright ownership. The ASF licenses this file
|
|
to you under the Apache License, Version 2.0 (the
|
|
"License"); you may not use this file except in compliance
|
|
with the License. You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing,
|
|
software distributed under the License is distributed on an
|
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
KIND, either express or implied. See the License for the
|
|
specific language governing permissions and limitations
|
|
under the License.
|
|
|
|
|
|
Suppored Go releases
|
|
====================
|
|
|
|
Following the
|
|
[official Go release policy](https://golang.org/doc/devel/release#policy),
|
|
we support the latest two Go releases at the time of the Thrift release.
|
|
|
|
For example, at the time of Thrift v0.14.0 release,
|
|
the latest two Go releases are go1.15 and go1.14,
|
|
and those are the two Go releases supported by Thrift v0.14.*
|
|
(including v0.14.1 and v0.14.2 patch releases).
|
|
|
|
Because of Go's backward compatibility guarantee,
|
|
older Thrift libraries usually works with newer Go releases
|
|
(e.g. Thrift v0.14.* works with go1.16, although it's not officially supported),
|
|
but newer Thrift releases might use new APIs introduced in Go releases and no
|
|
longer work with older Go releases.
|
|
For example, Thrift v0.14.0 used APIs introduced in go1.13,
|
|
and as a result no longer works on go1.12.
|
|
|
|
|
|
Using Thrift with Go
|
|
====================
|
|
|
|
Thrift supports the currently officially supported Go releases (the latest 2).
|
|
|
|
After initializing the go modules file in your project, use the following
|
|
command to add the most recent version of the package:
|
|
|
|
$ go get github.com/apache/thrift
|
|
|
|
|
|
A note about optional fields
|
|
============================
|
|
|
|
The thrift-to-Go compiler tries to represent thrift IDL structs as Go structs.
|
|
We must be able to distinguish between optional fields that are set to their
|
|
default value and optional values which are actually unset, so the generated
|
|
code represents optional fields via pointers.
|
|
|
|
This is generally intuitive and works well much of the time, but Go does not
|
|
have a syntax for creating a pointer to a constant in a single expression. That
|
|
is, given a struct like
|
|
|
|
struct SomeIDLType {
|
|
OptionalField *int32
|
|
}
|
|
|
|
, the following will not compile:
|
|
|
|
x := &SomeIDLType{
|
|
OptionalField: &(3),
|
|
}
|
|
|
|
(Nor is there any other syntax that's built in to the language)
|
|
|
|
As such, we provide some helpers that do just this under lib/go/thrift/. E.g.,
|
|
|
|
x := &SomeIDLType{
|
|
OptionalField: thrift.Int32Ptr(3),
|
|
}
|
|
|
|
And so on. The code generator also creates analogous helpers for user-defined
|
|
typedefs and enums.
|
|
|
|
Adding custom tags to generated Thrift structs
|
|
==============================================
|
|
|
|
You can add tags to the auto-generated thrift structs using the following format:
|
|
|
|
struct foo {
|
|
1: required string Bar (go.tag = "some_tag:\"some_tag_value\"")
|
|
}
|
|
|
|
which will generate:
|
|
|
|
type Foo struct {
|
|
Bar string `thrift:"bar,1,required" some_tag:"some_tag_value"`
|
|
}
|
|
|
|
A note about server handler implementations
|
|
===========================================
|
|
|
|
The context object passed into the server handler function will be canceled when
|
|
the client closes the connection (this is a best effort check, not a guarantee
|
|
-- there's no guarantee that the context object is always canceled when client
|
|
closes the connection, but when it's canceled you can always assume the client
|
|
closed the connection). When implementing Go Thrift server, you can take
|
|
advantage of that to abandon requests that's no longer needed:
|
|
|
|
func MyEndpoint(ctx context.Context, req *thriftRequestType) (*thriftResponseType, error) {
|
|
...
|
|
if ctx.Err() == context.Canceled {
|
|
return nil, thrift.ErrAbandonRequest
|
|
}
|
|
...
|
|
}
|
|
|
|
This feature would add roughly 1 millisecond of latency overhead to the server
|
|
handlers (along with roughly 2 goroutines per request).
|
|
If that is unacceptable, it can be disabled by having this line early in your
|
|
main function:
|
|
|
|
thrift.ServerConnectivityCheckInterval = 0
|
|
|
|
Please be advised that due to a
|
|
[Go runtime bug](https://github.com/golang/go/issues/27707), currently
|
|
if this interval is set to a value too low (for example, 1ms), it might cause
|
|
excessive cpu overhead.
|
|
|
|
This feature is also only enabled on non-oneway endpoints.
|
|
|
|
A note about server stop implementations
|
|
========================================
|
|
|
|
[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
|
|
the last received request to be handled, as the time spent by Stop
|
|
may sometimes be too long:
|
|
* When socket timeout is not set, server might be hanged before all active
|
|
clients to finish handling the last received request.
|
|
* When the socket timeout is too long (e.g one hour), server will
|
|
hang for that duration before all active clients to finish handling the
|
|
last received request.
|
|
|
|
To prevent Stop from hanging for too long, you can set
|
|
thrift.ServerStopTimeout in your main or init function:
|
|
|
|
thrift.ServerStopTimeout = <max_duration_to_stop>
|
|
|
|
If it's set to <=0, the feature will be disabled (by default), and server
|
|
will wait for all the client connections to be closed gracefully with
|
|
zero err time. Otherwise, the stop will wait for all the client
|
|
connections to be closed gracefully util thrift.ServerStopTimeout is
|
|
reached, and client connections that are not closed after thrift.ServerStopTimeout
|
|
will be closed abruptly which may cause some client errors. |