summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuxuan 'fishy' Wang <yuxuan.wang@reddit.com>2022-03-15 15:22:15 -0700
committerYuxuan 'fishy' Wang <fishywang@gmail.com>2022-03-15 21:39:38 -0700
commit6433994ee794fa4cd0d7dd862f83cedbfb72c23b (patch)
tree8f3e5d44c3b982d9902420e24ac92828b0738521
parentb941b1124834d38daaa0e4355655b4ce63b80d3e (diff)
downloadthrift-6433994ee794fa4cd0d7dd862f83cedbfb72c23b.tar.gz
THRIFT-5539: Decouple TDuplicateToProtocol out of TDebugProtocol
Client: go Currently go's TDebugProtocol does two things: log the read/writes, and duplicate all the reads/writes to another TProtocol. For people who only need the second feature, even if they use NopLogger for the logging part, they still need to pay the price of all the fmt.Sprintf calls used by logging, and on some cases those fmt.Sprintf calls alone can cause significant CPU to be wasted (in one of our services fmt.Sprintf called by TDebugProtocol used ~10% of CPU). Create a dedicated TDuplicateToProtocol to reduce cpu waste, and mark TDebugProtocol.DuplicateTo as deprecated.
-rw-r--r--CHANGES.md6
-rw-r--r--lib/go/thrift/debug_protocol.go2
-rw-r--r--lib/go/thrift/duplicate_protocol.go311
3 files changed, 319 insertions, 0 deletions
diff --git a/CHANGES.md b/CHANGES.md
index 805c0d94a..8481d1173 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,11 @@
# Apache Thrift Changelog
+## 0.17.0
+
+### Go
+
+- [THRIFT-5539](https://issues.apache.org/jira/browse/THRIFT-5539) - `TDebugProtocol.DuplicateTo` is now deprecated, `TDuplicateToProtocol` has been provided as the replacement
+
## 0.16.0
### Known Open Issues (Blocker or Critical)
diff --git a/lib/go/thrift/debug_protocol.go b/lib/go/thrift/debug_protocol.go
index fdf9bfec1..c1f4fab4c 100644
--- a/lib/go/thrift/debug_protocol.go
+++ b/lib/go/thrift/debug_protocol.go
@@ -45,6 +45,8 @@ type TDebugProtocol struct {
// This feature is not available from TDebugProtocolFactory. In order to
// use it you have to construct TDebugProtocol directly, or set DuplicateTo
// field after getting a TDebugProtocol from the factory.
+ //
+ // Deprecated: Please use TDuplicateToProtocol instead.
DuplicateTo TProtocol
}
diff --git a/lib/go/thrift/duplicate_protocol.go b/lib/go/thrift/duplicate_protocol.go
new file mode 100644
index 000000000..c23d548c3
--- /dev/null
+++ b/lib/go/thrift/duplicate_protocol.go
@@ -0,0 +1,311 @@
+/*
+ * 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.
+ */
+
+package thrift
+
+import (
+ "context"
+)
+
+type TDuplicateToProtocol struct {
+ // Required. The actual TProtocol to do the read/write.
+ Delegate TProtocol
+
+ // Required. An TProtocol to duplicate everything read/written from Delegate.
+ //
+ // A typical use case of this is to use TSimpleJSONProtocol wrapping
+ // TMemoryBuffer in a middleware to json logging requests/responses,
+ // or wrapping a TTransport that counts bytes written to get the payload
+ // sizes.
+ //
+ // DuplicateTo will be used as write only. For read calls on
+ // TDuplicateToProtocol, the result read from Delegate will be written
+ // to DuplicateTo.
+ DuplicateTo TProtocol
+}
+
+func (tdtp *TDuplicateToProtocol) WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqid int32) error {
+ err := tdtp.Delegate.WriteMessageBegin(ctx, name, typeId, seqid)
+ tdtp.DuplicateTo.WriteMessageBegin(ctx, name, typeId, seqid)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteMessageEnd(ctx context.Context) error {
+ err := tdtp.Delegate.WriteMessageEnd(ctx)
+ tdtp.DuplicateTo.WriteMessageEnd(ctx)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteStructBegin(ctx context.Context, name string) error {
+ err := tdtp.Delegate.WriteStructBegin(ctx, name)
+ tdtp.DuplicateTo.WriteStructBegin(ctx, name)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteStructEnd(ctx context.Context) error {
+ err := tdtp.Delegate.WriteStructEnd(ctx)
+ tdtp.DuplicateTo.WriteStructEnd(ctx)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error {
+ err := tdtp.Delegate.WriteFieldBegin(ctx, name, typeId, id)
+ tdtp.DuplicateTo.WriteFieldBegin(ctx, name, typeId, id)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteFieldEnd(ctx context.Context) error {
+ err := tdtp.Delegate.WriteFieldEnd(ctx)
+ tdtp.DuplicateTo.WriteFieldEnd(ctx)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteFieldStop(ctx context.Context) error {
+ err := tdtp.Delegate.WriteFieldStop(ctx)
+ tdtp.DuplicateTo.WriteFieldStop(ctx)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error {
+ err := tdtp.Delegate.WriteMapBegin(ctx, keyType, valueType, size)
+ tdtp.DuplicateTo.WriteMapBegin(ctx, keyType, valueType, size)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteMapEnd(ctx context.Context) error {
+ err := tdtp.Delegate.WriteMapEnd(ctx)
+ tdtp.DuplicateTo.WriteMapEnd(ctx)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteListBegin(ctx context.Context, elemType TType, size int) error {
+ err := tdtp.Delegate.WriteListBegin(ctx, elemType, size)
+ tdtp.DuplicateTo.WriteListBegin(ctx, elemType, size)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteListEnd(ctx context.Context) error {
+ err := tdtp.Delegate.WriteListEnd(ctx)
+ tdtp.DuplicateTo.WriteListEnd(ctx)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteSetBegin(ctx context.Context, elemType TType, size int) error {
+ err := tdtp.Delegate.WriteSetBegin(ctx, elemType, size)
+ tdtp.DuplicateTo.WriteSetBegin(ctx, elemType, size)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteSetEnd(ctx context.Context) error {
+ err := tdtp.Delegate.WriteSetEnd(ctx)
+ tdtp.DuplicateTo.WriteSetEnd(ctx)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteBool(ctx context.Context, value bool) error {
+ err := tdtp.Delegate.WriteBool(ctx, value)
+ tdtp.DuplicateTo.WriteBool(ctx, value)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteByte(ctx context.Context, value int8) error {
+ err := tdtp.Delegate.WriteByte(ctx, value)
+ tdtp.DuplicateTo.WriteByte(ctx, value)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteI16(ctx context.Context, value int16) error {
+ err := tdtp.Delegate.WriteI16(ctx, value)
+ tdtp.DuplicateTo.WriteI16(ctx, value)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteI32(ctx context.Context, value int32) error {
+ err := tdtp.Delegate.WriteI32(ctx, value)
+ tdtp.DuplicateTo.WriteI32(ctx, value)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteI64(ctx context.Context, value int64) error {
+ err := tdtp.Delegate.WriteI64(ctx, value)
+ tdtp.DuplicateTo.WriteI64(ctx, value)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteDouble(ctx context.Context, value float64) error {
+ err := tdtp.Delegate.WriteDouble(ctx, value)
+ tdtp.DuplicateTo.WriteDouble(ctx, value)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteString(ctx context.Context, value string) error {
+ err := tdtp.Delegate.WriteString(ctx, value)
+ tdtp.DuplicateTo.WriteString(ctx, value)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) WriteBinary(ctx context.Context, value []byte) error {
+ err := tdtp.Delegate.WriteBinary(ctx, value)
+ tdtp.DuplicateTo.WriteBinary(ctx, value)
+ return err
+}
+
+func (tdtp *TDuplicateToProtocol) ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqid int32, err error) {
+ name, typeId, seqid, err = tdtp.Delegate.ReadMessageBegin(ctx)
+ tdtp.DuplicateTo.WriteMessageBegin(ctx, name, typeId, seqid)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadMessageEnd(ctx context.Context) (err error) {
+ err = tdtp.Delegate.ReadMessageEnd(ctx)
+ tdtp.DuplicateTo.WriteMessageEnd(ctx)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadStructBegin(ctx context.Context) (name string, err error) {
+ name, err = tdtp.Delegate.ReadStructBegin(ctx)
+ tdtp.DuplicateTo.WriteStructBegin(ctx, name)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadStructEnd(ctx context.Context) (err error) {
+ err = tdtp.Delegate.ReadStructEnd(ctx)
+ tdtp.DuplicateTo.WriteStructEnd(ctx)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadFieldBegin(ctx context.Context) (name string, typeId TType, id int16, err error) {
+ name, typeId, id, err = tdtp.Delegate.ReadFieldBegin(ctx)
+ tdtp.DuplicateTo.WriteFieldBegin(ctx, name, typeId, id)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadFieldEnd(ctx context.Context) (err error) {
+ err = tdtp.Delegate.ReadFieldEnd(ctx)
+ tdtp.DuplicateTo.WriteFieldEnd(ctx)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, err error) {
+ keyType, valueType, size, err = tdtp.Delegate.ReadMapBegin(ctx)
+ tdtp.DuplicateTo.WriteMapBegin(ctx, keyType, valueType, size)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadMapEnd(ctx context.Context) (err error) {
+ err = tdtp.Delegate.ReadMapEnd(ctx)
+ tdtp.DuplicateTo.WriteMapEnd(ctx)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadListBegin(ctx context.Context) (elemType TType, size int, err error) {
+ elemType, size, err = tdtp.Delegate.ReadListBegin(ctx)
+ tdtp.DuplicateTo.WriteListBegin(ctx, elemType, size)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadListEnd(ctx context.Context) (err error) {
+ err = tdtp.Delegate.ReadListEnd(ctx)
+ tdtp.DuplicateTo.WriteListEnd(ctx)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadSetBegin(ctx context.Context) (elemType TType, size int, err error) {
+ elemType, size, err = tdtp.Delegate.ReadSetBegin(ctx)
+ tdtp.DuplicateTo.WriteSetBegin(ctx, elemType, size)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadSetEnd(ctx context.Context) (err error) {
+ err = tdtp.Delegate.ReadSetEnd(ctx)
+ tdtp.DuplicateTo.WriteSetEnd(ctx)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadBool(ctx context.Context) (value bool, err error) {
+ value, err = tdtp.Delegate.ReadBool(ctx)
+ tdtp.DuplicateTo.WriteBool(ctx, value)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadByte(ctx context.Context) (value int8, err error) {
+ value, err = tdtp.Delegate.ReadByte(ctx)
+ tdtp.DuplicateTo.WriteByte(ctx, value)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadI16(ctx context.Context) (value int16, err error) {
+ value, err = tdtp.Delegate.ReadI16(ctx)
+ tdtp.DuplicateTo.WriteI16(ctx, value)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadI32(ctx context.Context) (value int32, err error) {
+ value, err = tdtp.Delegate.ReadI32(ctx)
+ tdtp.DuplicateTo.WriteI32(ctx, value)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadI64(ctx context.Context) (value int64, err error) {
+ value, err = tdtp.Delegate.ReadI64(ctx)
+ tdtp.DuplicateTo.WriteI64(ctx, value)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadDouble(ctx context.Context) (value float64, err error) {
+ value, err = tdtp.Delegate.ReadDouble(ctx)
+ tdtp.DuplicateTo.WriteDouble(ctx, value)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadString(ctx context.Context) (value string, err error) {
+ value, err = tdtp.Delegate.ReadString(ctx)
+ tdtp.DuplicateTo.WriteString(ctx, value)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) ReadBinary(ctx context.Context) (value []byte, err error) {
+ value, err = tdtp.Delegate.ReadBinary(ctx)
+ tdtp.DuplicateTo.WriteBinary(ctx, value)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) Skip(ctx context.Context, fieldType TType) (err error) {
+ err = tdtp.Delegate.Skip(ctx, fieldType)
+ tdtp.DuplicateTo.Skip(ctx, fieldType)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) Flush(ctx context.Context) (err error) {
+ err = tdtp.Delegate.Flush(ctx)
+ tdtp.DuplicateTo.Flush(ctx)
+ return
+}
+
+func (tdtp *TDuplicateToProtocol) Transport() TTransport {
+ return tdtp.Delegate.Transport()
+}
+
+// SetTConfiguration implements TConfigurationSetter for propagation.
+func (tdtp *TDuplicateToProtocol) SetTConfiguration(conf *TConfiguration) {
+ PropagateTConfiguration(tdtp.Delegate, conf)
+ PropagateTConfiguration(tdtp.DuplicateTo, conf)
+}
+
+var _ TConfigurationSetter = (*TDuplicateToProtocol)(nil)