Uploaded image for project: 'Thrift'
  1. Thrift
  2. THRIFT-1915 Multiplexing Services
  3. THRIFT-1914

Python: Support for Multiplexing Services on any Transport, Protocol and Server

    Details

    • Type: Sub-task
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 0.9.2
    • Component/s: Python - Library
    • Labels:
      None
    • Patch Info:
      Patch Available

      Description

      Motivation and Benefits

      We plan to use Thrift with a large number of functions communicating among (at least) three languages. To keep maintainability high, we hope to avoid a single service defined with a large number of functions. This would require monolithic, unwieldy service implementations as the number of functions grows.

      Breaking up our API into multiple IDLs gives us multiple abstract base classes, which provides more flexibility in the object-oriented design of our server platform.

      Before our changes, the alternative was to open up additional ports with smaller service implementations on each. We'd rather not open additional ports.

      Our Approach

      We pursued an approach with the following in mind:

      • No modifications to existing Thrift code.
      • No modification to the Thrift protocol as described in the whitepaper.
      • No modification to any TServer, TProtocol or TTransport.
      • No need for any new TServer implementation. Works with any TServer implementation.
      • Work with any combination of TServer, TProtocol or TTransport.
      • Avoid language-specific features, to ease implementation in other languages.

      Additions to Thrift

      Convenience class:

      • TProtocolDecorator (extends TProtocol). This is a no-op decorator around the TProtocol abstract class.

      For use by clients:

      • TMultiplexedProtocol (extends TProtocolDecorator). This decorates any TProtocol by modifying the behaviour of writeMessageBegin(TMessage) to change TMessage.name from function_name to service_name + separator + function_name.

      For use by the server:

      • TMultiplexedProcessor (implements TProcessor). It should be used to communicate with a client that was written using TMultiplexedProtocol. It removes service_name + separator from TMessage.name, turning it back into the standard message format. It then brokers the service request to the TProcessor which is registered to handle requests for that service.

      Sample Usage - Client

      In this example, we've chosen to use TBinaryProtocol with two services: Calculator and WeatherReport.

      TSocket transport = new TSocket("localhost", 9090);
      transport.open();
      
      TBinaryProtocol protocol = new TBinaryProtocol(transport);
      
      TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol, "Calculator");
      Calculator.Client service = new Calculator.Client(mp);
      
      TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol, "WeatherReport");
      WeatherReport.Client service2 = new WeatherReport.Client(mp2);
      
      System.out.println(service.add(2,2));
      System.out.println(service2.getTemperature());
      

      Sample Usage - Server

      TMultiplexedProcessor processor = new TMultiplexedProcessor();
      
      processor.registerProcessor(
          "Calculator",
          new Calculator.Processor(new CalculatorHandler()));
      
      processor.registerProcessor(
          "WeatherReport",
          new WeatherReport.Processor(new WeatherReportHandler()));
      
      TServerTransport t = new TServerSocket(9090);
      TSimpleServer server = new TSimpleServer(processor, t);
      
      server.serve();
      
      1. python_multiplex.patch
        7 kB
        Doug MacEachern
      2. python3_multiplex.patch
        3 kB
        liuzh

        Issue Links

          Activity

          Hide
          hudson Hudson added a comment -

          FAILURE: Integrated in Thrift #1146 (See https://builds.apache.org/job/Thrift/1146/)
          THRIFT-1914 Python: Support for Multiplexing Services on any (roger: rev 879cab2cea799625635d861f5beb89039da5f38c)

          • lib/py/src/TMultiplexedProcessor.py
          • lib/py/src/protocol/TProtocolDecorator.py
          • lib/py/src/protocol/TMultiplexedProtocol.py
          • test/py/TestClient.py
          • test/py/TestServer.py
          Show
          hudson Hudson added a comment - FAILURE: Integrated in Thrift #1146 (See https://builds.apache.org/job/Thrift/1146/ ) THRIFT-1914 Python: Support for Multiplexing Services on any (roger: rev 879cab2cea799625635d861f5beb89039da5f38c) lib/py/src/TMultiplexedProcessor.py lib/py/src/protocol/TProtocolDecorator.py lib/py/src/protocol/TMultiplexedProtocol.py test/py/TestClient.py test/py/TestServer.py
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user jfarrell closed the pull request at:

          https://github.com/apache/thrift/pull/82

          Show
          githubbot ASF GitHub Bot added a comment - Github user jfarrell closed the pull request at: https://github.com/apache/thrift/pull/82
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user bufferoverflow commented on the pull request:

          https://github.com/apache/thrift/pull/82#issuecomment-42109884

          please close this issue. its's committed via #103

          Show
          githubbot ASF GitHub Bot added a comment - Github user bufferoverflow commented on the pull request: https://github.com/apache/thrift/pull/82#issuecomment-42109884 please close this issue. its's committed via #103
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user asfgit closed the pull request at:

          https://github.com/apache/thrift/pull/103

          Show
          githubbot ASF GitHub Bot added a comment - Github user asfgit closed the pull request at: https://github.com/apache/thrift/pull/103
          Hide
          roger.meier Roger Meier added a comment -

          committed.

          fixed error message reported by djwatson
          and use other method proposed by haijunz

          -roger

          Show
          roger.meier Roger Meier added a comment - committed. fixed error message reported by djwatson and use other method proposed by haijunz -roger
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user haijunz commented on a diff in the pull request:

          https://github.com/apache/thrift/pull/82#discussion_r12255168

          — Diff: lib/py/src/TMultiplexedProcessor.py —
          @@ -0,0 +1,58 @@
          +#
          +# 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.
          +#
          +
          +from thrift.Thrift import TProcessor, TMessageType, TException
          +from thrift.protocol import TProtocolDecorator, TMultiplexedProtocol
          +
          +class TMultiplexedProcessor(TProcessor):
          + def _init_(self):
          + self.services = {}
          +
          + def registerProcessor(self, serviceName, processor):
          + self.services[serviceName] = processor
          +
          + def process(self, iprot, oprot):
          + (name, type, seqid) = iprot.readMessageBegin();
          + if type != TMessageType.CALL & type != TMessageType.ONEWAY:
          + raise TException("This should not have happened!?")
          +
          + index = name.find(TMultiplexedProtocol.SEPARATOR)
          + if index < 0:
          + raise TException("Service name not found in message name: " + name + ". Did you forget to use TMultiplexProtocol in your client?")
          +
          + serviceName = name[0:index]
          + call = name[index+len(TMultiplexedProtocol.SEPARATOR):]
          + if not self.services.has_key(serviceName):
          — End diff –

          Can you use in instead:
          if not serviceName in self.services:

          Show
          githubbot ASF GitHub Bot added a comment - Github user haijunz commented on a diff in the pull request: https://github.com/apache/thrift/pull/82#discussion_r12255168 — Diff: lib/py/src/TMultiplexedProcessor.py — @@ -0,0 +1,58 @@ +# +# 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. +# + +from thrift.Thrift import TProcessor, TMessageType, TException +from thrift.protocol import TProtocolDecorator, TMultiplexedProtocol + +class TMultiplexedProcessor(TProcessor): + def _ init _(self): + self.services = {} + + def registerProcessor(self, serviceName, processor): + self.services [serviceName] = processor + + def process(self, iprot, oprot): + (name, type, seqid) = iprot.readMessageBegin(); + if type != TMessageType.CALL & type != TMessageType.ONEWAY: + raise TException("This should not have happened!?") + + index = name.find(TMultiplexedProtocol.SEPARATOR) + if index < 0: + raise TException("Service name not found in message name: " + name + ". Did you forget to use TMultiplexProtocol in your client?") + + serviceName = name [0:index] + call = name [index+len(TMultiplexedProtocol.SEPARATOR):] + if not self.services.has_key(serviceName): — End diff – Can you use in instead: if not serviceName in self.services:
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user haijunz commented on a diff in the pull request:

          https://github.com/apache/thrift/pull/82#discussion_r12252798

          — Diff: lib/py/src/protocol/TProtocolDecorator.py —
          @@ -0,0 +1,42 @@
          +#
          +# 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.
          +#
          +
          +from thrift.protocol.TProtocol import TProtocolBase
          +from types import *
          +
          +class TProtocolDecorator():
          + def _init_(self, protocol):
          + TProtocolBase(protocol)
          + self.protocol = protocol
          +
          + def _getattr_(self, name):
          + if hasattr(self.protocol, name):
          + member = getattr(self.protocol, name)
          + if type(member) in [MethodType, UnboundMethodType, FunctionType, LambdaType, BuiltinFunctionType, BuiltinMethodType]:
          — End diff –

          Is UnboundMethodType still needed?

          Show
          githubbot ASF GitHub Bot added a comment - Github user haijunz commented on a diff in the pull request: https://github.com/apache/thrift/pull/82#discussion_r12252798 — Diff: lib/py/src/protocol/TProtocolDecorator.py — @@ -0,0 +1,42 @@ +# +# 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. +# + +from thrift.protocol.TProtocol import TProtocolBase +from types import * + +class TProtocolDecorator(): + def _ init _(self, protocol): + TProtocolBase(protocol) + self.protocol = protocol + + def _ getattr _(self, name): + if hasattr(self.protocol, name): + member = getattr(self.protocol, name) + if type(member) in [MethodType, UnboundMethodType, FunctionType, LambdaType, BuiltinFunctionType, BuiltinMethodType] : — End diff – Is UnboundMethodType still needed?
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user djwatson commented on a diff in the pull request:

          https://github.com/apache/thrift/pull/82#discussion_r12213289

          — Diff: lib/py/src/TMultiplexedProcessor.py —
          @@ -0,0 +1,58 @@
          +#
          +# 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.
          +#
          +
          +from thrift.Thrift import TProcessor, TMessageType, TException
          +from thrift.protocol import TProtocolDecorator, TMultiplexedProtocol
          +
          +class TMultiplexedProcessor(TProcessor):
          + def _init_(self):
          + self.services = {}
          +
          + def registerProcessor(self, serviceName, processor):
          + self.services[serviceName] = processor
          +
          + def process(self, iprot, oprot):
          + (name, type, seqid) = iprot.readMessageBegin();
          + if type != TMessageType.CALL & type != TMessageType.ONEWAY:
          + raise TException("This should not have happened!?")
          — End diff –

          Can we get a better error message? "TMultiplex protocol only supports CALL & Oneway" or something

          Show
          githubbot ASF GitHub Bot added a comment - Github user djwatson commented on a diff in the pull request: https://github.com/apache/thrift/pull/82#discussion_r12213289 — Diff: lib/py/src/TMultiplexedProcessor.py — @@ -0,0 +1,58 @@ +# +# 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. +# + +from thrift.Thrift import TProcessor, TMessageType, TException +from thrift.protocol import TProtocolDecorator, TMultiplexedProtocol + +class TMultiplexedProcessor(TProcessor): + def _ init _(self): + self.services = {} + + def registerProcessor(self, serviceName, processor): + self.services [serviceName] = processor + + def process(self, iprot, oprot): + (name, type, seqid) = iprot.readMessageBegin(); + if type != TMessageType.CALL & type != TMessageType.ONEWAY: + raise TException("This should not have happened!?") — End diff – Can we get a better error message? "TMultiplex protocol only supports CALL & Oneway" or something
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user Jens-G commented on the pull request:

          https://github.com/apache/thrift/pull/82#issuecomment-41959894

          So this one is obsolete?

          Show
          githubbot ASF GitHub Bot added a comment - Github user Jens-G commented on the pull request: https://github.com/apache/thrift/pull/82#issuecomment-41959894 So this one is obsolete?
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user smallfish commented on the pull request:

          https://github.com/apache/thrift/pull/82#issuecomment-41000854

          @bufferoverflow
          Sorry, submitted with the wrong user/email several commits.
          I create new pull request: #103, it's clean.

          Show
          githubbot ASF GitHub Bot added a comment - Github user smallfish commented on the pull request: https://github.com/apache/thrift/pull/82#issuecomment-41000854 @bufferoverflow Sorry, submitted with the wrong user/email several commits. I create new pull request: #103, it's clean.
          Hide
          githubbot ASF GitHub Bot added a comment -

          GitHub user smallfish opened a pull request:

          https://github.com/apache/thrift/pull/103

          THRIFT-1914 Python: Support for Multiplexing Services on any Transport

          copy patch from: https://issues.apache.org/jira/browse/THRIFT-1914 add some testcases.

          add new options multiple, if set True, will test ThriftTest and SecondService.

          run server:

          $ python TestServer.py --port=9999 --multiple -v TSimpleServer

          run client:

          $ python TestClient.py --host=127.0.0.1 --port=9999 --multiple
          ...................
          ----------------------------------------------------------------------
          Ran 19 tests in 0.693s

          OK

          _END_

          You can merge this pull request into a Git repository by running:

          $ git pull https://github.com/smallfish/thrift master

          Alternatively you can review and apply these changes as the patch at:

          https://github.com/apache/thrift/pull/103.patch

          To close this pull request, make a commit to your master/trunk branch
          with (at least) the following in the commit message:

          This closes #103


          commit 7aaea7ef4e6f44097b02543fa2e62597eae9d61e
          Author: smallfish <smallfish.xy@gmail.com>
          Date: 2014-04-22T03:26:52Z

          THRIFT-1914 Python: Support for Multiplexing Services on any Transport


          Show
          githubbot ASF GitHub Bot added a comment - GitHub user smallfish opened a pull request: https://github.com/apache/thrift/pull/103 THRIFT-1914 Python: Support for Multiplexing Services on any Transport copy patch from: https://issues.apache.org/jira/browse/THRIFT-1914 add some testcases. add new options multiple, if set True, will test ThriftTest and SecondService. run server: $ python TestServer.py --port=9999 --multiple -v TSimpleServer run client: $ python TestClient.py --host=127.0.0.1 --port=9999 --multiple ................... ---------------------------------------------------------------------- Ran 19 tests in 0.693s OK _ END _ You can merge this pull request into a Git repository by running: $ git pull https://github.com/smallfish/thrift master Alternatively you can review and apply these changes as the patch at: https://github.com/apache/thrift/pull/103.patch To close this pull request, make a commit to your master/trunk branch with (at least) the following in the commit message: This closes #103 commit 7aaea7ef4e6f44097b02543fa2e62597eae9d61e Author: smallfish <smallfish.xy@gmail.com> Date: 2014-04-22T03:26:52Z THRIFT-1914 Python: Support for Multiplexing Services on any Transport
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user bufferoverflow commented on a diff in the pull request:

          https://github.com/apache/thrift/pull/82#discussion_r11825463

          — Diff: test/py/TestServer.py —
          @@ -201,7 +217,7 @@ def testMulti(self, arg0, arg1, arg2, arg3, arg4, arg5):
          host = None
          if options.ssl:
          from thrift.transport import TSSLSocket

          • transport = TSSLSocket.TSSLServerSocket(host, options.port, certfile='../keys/server.pem')
            + transport = TSSLSocket.TSSLServerSocket(host, options.port, certfile='test_cert.pem')
              • End diff –

          could you please keep ../keys/server.pem here? test_cert.pem is not available anymore

          Show
          githubbot ASF GitHub Bot added a comment - Github user bufferoverflow commented on a diff in the pull request: https://github.com/apache/thrift/pull/82#discussion_r11825463 — Diff: test/py/TestServer.py — @@ -201,7 +217,7 @@ def testMulti(self, arg0, arg1, arg2, arg3, arg4, arg5): host = None if options.ssl: from thrift.transport import TSSLSocket transport = TSSLSocket.TSSLServerSocket(host, options.port, certfile='../keys/server.pem') + transport = TSSLSocket.TSSLServerSocket(host, options.port, certfile='test_cert.pem') End diff – could you please keep ../keys/server.pem here? test_cert.pem is not available anymore
          Hide
          smallfish smallfish added a comment -

          Yes, Nothing to be added.

          Show
          smallfish smallfish added a comment - Yes, Nothing to be added.
          Hide
          wko12 Wing-Hong Andrew Ko added a comment -

          Thank you for the progress! Anything else needed?

          Show
          wko12 Wing-Hong Andrew Ko added a comment - Thank you for the progress! Anything else needed?
          Hide
          smallfish smallfish added a comment -

          I send a Github pull-request, this: https://github.com/apache/thrift/pull/82

          Wrote some testcase for multiplexing services, ThriftTest and SecondService.

          Show
          smallfish smallfish added a comment - I send a Github pull-request, this: https://github.com/apache/thrift/pull/82 Wrote some testcase for multiplexing services, ThriftTest and SecondService.
          Hide
          githubbot ASF GitHub Bot added a comment -

          GitHub user smallfish opened a pull request:

          https://github.com/apache/thrift/pull/82

          THRIFT-1914 Python: Support for Multiplexing Services on any Transport

          copy patch from: https://issues.apache.org/jira/browse/THRIFT-1914 add some testcases.

          add new options `multiple`, if set `True`, will test `ThriftTest` and `SecondService`.

          run server:

          $ python TestServer.py --port=9999 --multiple -v TSimpleServer

          run client:

          $ python TestClient.py --host=127.0.0.1 --port=9999 --multiple
          ...................
          ----------------------------------------------------------------------
          Ran 19 tests in 0.693s

          OK

          You can merge this pull request into a Git repository by running:

          $ git pull https://github.com/smallfish/thrift master

          Alternatively you can review and apply these changes as the patch at:

          https://github.com/apache/thrift/pull/82.patch

          To close this pull request, make a commit to your master/trunk branch
          with (at least) the following in the commit message:

          This closes #82


          commit 4b5e276a43371b5d5cccbf9ca9fbcea790ae6881
          Author: smallfish <smallfish.xy@gmail.com>
          Date: 2014-03-04T16:34:59Z

          THRIFT-1914 Python: Support for Multiplexing Services on any Transport, Protocol and Server, add testcases


          Show
          githubbot ASF GitHub Bot added a comment - GitHub user smallfish opened a pull request: https://github.com/apache/thrift/pull/82 THRIFT-1914 Python: Support for Multiplexing Services on any Transport copy patch from: https://issues.apache.org/jira/browse/THRIFT-1914 add some testcases. add new options `multiple`, if set `True`, will test `ThriftTest` and `SecondService`. run server: $ python TestServer.py --port=9999 --multiple -v TSimpleServer run client: $ python TestClient.py --host=127.0.0.1 --port=9999 --multiple ................... ---------------------------------------------------------------------- Ran 19 tests in 0.693s OK You can merge this pull request into a Git repository by running: $ git pull https://github.com/smallfish/thrift master Alternatively you can review and apply these changes as the patch at: https://github.com/apache/thrift/pull/82.patch To close this pull request, make a commit to your master/trunk branch with (at least) the following in the commit message: This closes #82 commit 4b5e276a43371b5d5cccbf9ca9fbcea790ae6881 Author: smallfish <smallfish.xy@gmail.com> Date: 2014-03-04T16:34:59Z THRIFT-1914 Python: Support for Multiplexing Services on any Transport, Protocol and Server, add testcases
          Hide
          henrique Henrique Mendonça added a comment -

          Thanks a lot for the patches!
          Would you guys be able to provide a basic unit-test coverage for all this by extending the current python unit-test?
          That would be great

          Cheers,
          Henrique

          Show
          henrique Henrique Mendonça added a comment - Thanks a lot for the patches! Would you guys be able to provide a basic unit-test coverage for all this by extending the current python unit-test? That would be great Cheers, Henrique
          Hide
          wko12 Wing-Hong Andrew Ko added a comment -

          The patch containing multiplexed support for javascript support was recently added. Would appreciate if the python support was also available!

          Show
          wko12 Wing-Hong Andrew Ko added a comment - The patch containing multiplexed support for javascript support was recently added. Would appreciate if the python support was also available!
          Hide
          liocn liuzh added a comment -

          According to file(python_multiplex.patch) Modification

          Show
          liocn liuzh added a comment - According to file(python_multiplex.patch) Modification
          Hide
          dougm Doug MacEachern added a comment -

          Based on Walter Huf's multiplex.py from THRIFT-563

          Show
          dougm Doug MacEachern added a comment - Based on Walter Huf's multiplex.py from THRIFT-563

            People

            • Assignee:
              roger.meier Roger Meier
              Reporter:
              dougm Doug MacEachern
            • Votes:
              2 Vote for this issue
              Watchers:
              8 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development