[ 
https://issues.apache.org/jira/browse/THRIFT-4312?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Walter Weinmann updated THRIFT-4312:
------------------------------------
    Description: 
h3. Connecting the Erlang client with the Python server gives connection error:
h3. 
h4. Erlang client:
h4. 
h4. 

{{
-module(client).

-include("calculator_thrift.hrl").

-export([t/0]).

p(X) ->
    io:format("~p~n", [X]),
    ok.

t() ->
    Port = 9090,

    {ok, Client0} = thrift_client_util:new("localhost",
                                           Port,
                                           calculator_thrift,
                                           []),

    {Client1, {ok, ok}} = thrift_client:call(Client0, ping, []),
    io:format("ping~n", []),

    {Client2, {ok, Sum}} = thrift_client:call(Client1, add,  [1, 1]),
    io:format("1+1=~p~n", [Sum]),

    {Client3, {ok, Sum1}} = thrift_client:call(Client2, add, [1, 4]),
    io:format("1+4=~p~n", [Sum1]),

    Work = #'Work'{op=?TUTORIAL_OPERATION_SUBTRACT,
                 num1=15,
                 num2=10},
    {Client4, {ok, Diff}} = thrift_client:call(Client3, calculate, [1, Work]),
    io:format("15-10=~p~n", [Diff]),

    {Client5, {ok, Log}} = thrift_client:call(Client4, getStruct, [1]),
    io:format("Log: ~p~n", [Log]),

    Client6 =
        try
            Work1 = #'Work'{op=?TUTORIAL_OPERATION_DIVIDE,
                          num1=1,
                          num2=0},
            {ClientS1, {ok, _Quot}} = thrift_client:call(Client5, calculate, 
[2, Work1]),

            io:format("LAME: exception handling is broken~n", []),
            ClientS1
        catch
            throw:{ClientS2, Z} ->
                io:format("Got exception where expecting - the " ++
                          "following is NOT a problem!!!~n"),
                p(Z),
                ClientS2
        end,


    {Client7, {ok, ok}} = thrift_client:call(Client6, zip, []),
    io:format("zip~n", []),

    {_Client8, ok} = thrift_client:close(Client7),
    ok.
}}

h4. Python server:
h4. 

{{
#!/usr/bin/env python

# import glob
# import sys
# sys.path.append('gen-py')
# sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0])

from tutorial import Calculator
from tutorial.ttypes import InvalidOperation, Operation

from shared.ttypes import SharedStruct

from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer


class CalculatorHandler:
    def __init__(self):
        self.log = {}

    def ping(self):
        print('ping()')

    def add(self, n1, n2):
        print('add(%d,%d)' % (n1, n2))
        return n1 + n2

    def calculate(self, logid, work):
        print('calculate(%d, %r)' % (logid, work))

        if work.op == Operation.ADD:
            val = work.num1 + work.num2
        elif work.op == Operation.SUBTRACT:
            val = work.num1 - work.num2
        elif work.op == Operation.MULTIPLY:
            val = work.num1 * work.num2
        elif work.op == Operation.DIVIDE:
            if work.num2 == 0:
                x = InvalidOperation()
                x.whatOp = work.op
                x.why = 'Cannot divide by 0'
                raise x
            val = work.num1 / work.num2
        else:
            x = InvalidOperation()
            x.whatOp = work.op
            x.why = 'Invalid operation'
            raise x

        log = SharedStruct()
        log.key = logid
        log.value = '%d' % (val)
        self.log[logid] = log

        return val

    def getStruct(self, key):
        print('getStruct(%d)' % (key))
        return self.log[key]

    def zip(self):
        print('zip()')

if __name__ == '__main__':
    handler = CalculatorHandler()
    processor = Calculator.Processor(handler)
    transport = TSocket.TServerSocket(port=9090)
    tfactory = TTransport.TBufferedTransportFactory()
    pfactory = TBinaryProtocol.TBinaryProtocolFactory()

    server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)

    # You could do one of these for a multithreaded server
    # server = TServer.TThreadedServer(
    #     processor, transport, tfactory, pfactory)
    # server = TServer.TThreadPoolServer(
    #     processor, transport, tfactory, pfactory)

    print('Starting the server...')
    server.serve()
    print('done.')
}}

h4. Runtime protocol:
h4. 

{{
EBIN Path : 
D:\SoftDevelopment\Projects\erlang-and-thrift_idea\erlang-and-thrift\_build\default\lib\erlang_and_thrift\ebin
 
D:\SoftDevelopment\Projects\erlang-and-thrift_idea\erlang-and-thrift\_build\default\lib\jsx\ebin
 
D:\SoftDevelopment\Projects\erlang-and-thrift_idea\erlang-and-thrift\_build\default\lib\thrift\ebin
------------------------------------------
Eshell V9.0  (abort with ^G)
1> client:t().
** exception error: no match of right hand side value {error,econnrefused}
     in function  client:t/0 
(d:/SoftDevelopment/Projects/erlang-and-thrift_idea/erlang-and-thrift/_build/default/lib/erlang_and_thrift/src/client.erl,
 line 33)
2> Terminate batch job (Y/N)? y

D:\SoftDevelopment\Projects\erlang-and-thrift_idea\erlang-and-thrift>tcping64 
localhost 9090

Probing ::1:9090/tcp - Port is open - time=0.580ms
Probing ::1:9090/tcp - Port is open - time=0.622ms
Probing ::1:9090/tcp - Port is open - time=1.038ms
Probing ::1:9090/tcp - Port is open - time=1.050ms

Ping statistics for ::1:9090
     4 probes sent.
     4 successful, 0 failed.
Approximate trip times in milli-seconds:
     Minimum = 0.580ms, Maximum = 1.050ms, Average = 0.822ms
}}

  was:
h3. Connecting the Erlang client with the Python server gives connection error:
h3. 
h4. Erlang client:
h4. 
h4. *{{-module(client).

-include("calculator_thrift.hrl").

-export([t/0]).

p(X) ->
    io:format("~p~n", [X]),
    ok.

t() ->
    Port = 9090,

    {ok, Client0} = thrift_client_util:new("localhost",
                                           Port,
                                           calculator_thrift,
                                           []),

    {Client1, {ok, ok}} = thrift_client:call(Client0, ping, []),
    io:format("ping~n", []),

    {Client2, {ok, Sum}} = thrift_client:call(Client1, add,  [1, 1]),
    io:format("1+1=~p~n", [Sum]),

    {Client3, {ok, Sum1}} = thrift_client:call(Client2, add, [1, 4]),
    io:format("1+4=~p~n", [Sum1]),

    Work = #'Work'{op=?TUTORIAL_OPERATION_SUBTRACT,
                 num1=15,
                 num2=10},
    {Client4, {ok, Diff}} = thrift_client:call(Client3, calculate, [1, Work]),
    io:format("15-10=~p~n", [Diff]),

    {Client5, {ok, Log}} = thrift_client:call(Client4, getStruct, [1]),
    io:format("Log: ~p~n", [Log]),

    Client6 =
        try
            Work1 = #'Work'{op=?TUTORIAL_OPERATION_DIVIDE,
                          num1=1,
                          num2=0},
            {ClientS1, {ok, _Quot}} = thrift_client:call(Client5, calculate, 
[2, Work1]),

            io:format("LAME: exception handling is broken~n", []),
            ClientS1
        catch
            throw:{ClientS2, Z} ->
                io:format("Got exception where expecting - the " ++
                          "following is NOT a problem!!!~n"),
                p(Z),
                ClientS2
        end,


    {Client7, {ok, ok}} = thrift_client:call(Client6, zip, []),
    io:format("zip~n", []),

    {_Client8, ok} = thrift_client:close(Client7),
    ok.
}}

h4. Python server:
h4. 

{{#!/usr/bin/env python

# import glob
# import sys
# sys.path.append('gen-py')
# sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0])

from tutorial import Calculator
from tutorial.ttypes import InvalidOperation, Operation

from shared.ttypes import SharedStruct

from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer


class CalculatorHandler:
    def __init__(self):
        self.log = {}

    def ping(self):
        print('ping()')

    def add(self, n1, n2):
        print('add(%d,%d)' % (n1, n2))
        return n1 + n2

    def calculate(self, logid, work):
        print('calculate(%d, %r)' % (logid, work))

        if work.op == Operation.ADD:
            val = work.num1 + work.num2
        elif work.op == Operation.SUBTRACT:
            val = work.num1 - work.num2
        elif work.op == Operation.MULTIPLY:
            val = work.num1 * work.num2
        elif work.op == Operation.DIVIDE:
            if work.num2 == 0:
                x = InvalidOperation()
                x.whatOp = work.op
                x.why = 'Cannot divide by 0'
                raise x
            val = work.num1 / work.num2
        else:
            x = InvalidOperation()
            x.whatOp = work.op
            x.why = 'Invalid operation'
            raise x

        log = SharedStruct()
        log.key = logid
        log.value = '%d' % (val)
        self.log[logid] = log

        return val

    def getStruct(self, key):
        print('getStruct(%d)' % (key))
        return self.log[key]

    def zip(self):
        print('zip()')

if __name__ == '__main__':
    handler = CalculatorHandler()
    processor = Calculator.Processor(handler)
    transport = TSocket.TServerSocket(port=9090)
    tfactory = TTransport.TBufferedTransportFactory()
    pfactory = TBinaryProtocol.TBinaryProtocolFactory()

    server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)

    # You could do one of these for a multithreaded server
    # server = TServer.TThreadedServer(
    #     processor, transport, tfactory, pfactory)
    # server = TServer.TThreadPoolServer(
    #     processor, transport, tfactory, pfactory)

    print('Starting the server...')
    server.serve()
    print('done.')
}}

h4. Runtime protocol:
h4. 

{{EBIN Path : 
D:\SoftDevelopment\Projects\erlang-and-thrift_idea\erlang-and-thrift\_build\default\lib\erlang_and_thrift\ebin
 
D:\SoftDevelopment\Projects\erlang-and-thrift_idea\erlang-and-thrift\_build\default\lib\jsx\ebin
 
D:\SoftDevelopment\Projects\erlang-and-thrift_idea\erlang-and-thrift\_build\default\lib\thrift\ebin
------------------------------------------
Eshell V9.0  (abort with ^G)
1> client:t().
** exception error: no match of right hand side value {error,econnrefused}
     in function  client:t/0 
(d:/SoftDevelopment/Projects/erlang-and-thrift_idea/erlang-and-thrift/_build/default/lib/erlang_and_thrift/src/client.erl,
 line 33)
2> Terminate batch job (Y/N)? y

D:\SoftDevelopment\Projects\erlang-and-thrift_idea\erlang-and-thrift>tcping64 
localhost 9090

Probing ::1:9090/tcp - Port is open - time=0.580ms
Probing ::1:9090/tcp - Port is open - time=0.622ms
Probing ::1:9090/tcp - Port is open - time=1.038ms
Probing ::1:9090/tcp - Port is open - time=1.050ms

Ping statistics for ::1:9090
     4 probes sent.
     4 successful, 0 failed.
Approximate trip times in milli-seconds:
     Minimum = 0.580ms, Maximum = 1.050ms, Average = 0.822ms
}}


> Tutorial: Erlang client cannot connect to Python server: exception error: 
> econnrefused
> --------------------------------------------------------------------------------------
>
>                 Key: THRIFT-4312
>                 URL: https://issues.apache.org/jira/browse/THRIFT-4312
>             Project: Thrift
>          Issue Type: Bug
>          Components: Tutorial
>    Affects Versions: 0.10.0
>         Environment: Windows 10
> Erlang OTP 20
> Python 3.6.2
>            Reporter: Walter Weinmann
>            Priority: Critical
>
> h3. Connecting the Erlang client with the Python server gives connection 
> error:
> h3. 
> h4. Erlang client:
> h4. 
> h4. 
> {{
> -module(client).
> -include("calculator_thrift.hrl").
> -export([t/0]).
> p(X) ->
>     io:format("~p~n", [X]),
>     ok.
> t() ->
>     Port = 9090,
>     {ok, Client0} = thrift_client_util:new("localhost",
>                                            Port,
>                                            calculator_thrift,
>                                            []),
>     {Client1, {ok, ok}} = thrift_client:call(Client0, ping, []),
>     io:format("ping~n", []),
>     {Client2, {ok, Sum}} = thrift_client:call(Client1, add,  [1, 1]),
>     io:format("1+1=~p~n", [Sum]),
>     {Client3, {ok, Sum1}} = thrift_client:call(Client2, add, [1, 4]),
>     io:format("1+4=~p~n", [Sum1]),
>     Work = #'Work'{op=?TUTORIAL_OPERATION_SUBTRACT,
>                  num1=15,
>                  num2=10},
>     {Client4, {ok, Diff}} = thrift_client:call(Client3, calculate, [1, Work]),
>     io:format("15-10=~p~n", [Diff]),
>     {Client5, {ok, Log}} = thrift_client:call(Client4, getStruct, [1]),
>     io:format("Log: ~p~n", [Log]),
>     Client6 =
>         try
>             Work1 = #'Work'{op=?TUTORIAL_OPERATION_DIVIDE,
>                           num1=1,
>                           num2=0},
>             {ClientS1, {ok, _Quot}} = thrift_client:call(Client5, calculate, 
> [2, Work1]),
>             io:format("LAME: exception handling is broken~n", []),
>             ClientS1
>         catch
>             throw:{ClientS2, Z} ->
>                 io:format("Got exception where expecting - the " ++
>                           "following is NOT a problem!!!~n"),
>                 p(Z),
>                 ClientS2
>         end,
>     {Client7, {ok, ok}} = thrift_client:call(Client6, zip, []),
>     io:format("zip~n", []),
>     {_Client8, ok} = thrift_client:close(Client7),
>     ok.
> }}
> h4. Python server:
> h4. 
> {{
> #!/usr/bin/env python
> # import glob
> # import sys
> # sys.path.append('gen-py')
> # sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0])
> from tutorial import Calculator
> from tutorial.ttypes import InvalidOperation, Operation
> from shared.ttypes import SharedStruct
> from thrift.transport import TSocket
> from thrift.transport import TTransport
> from thrift.protocol import TBinaryProtocol
> from thrift.server import TServer
> class CalculatorHandler:
>     def __init__(self):
>         self.log = {}
>     def ping(self):
>         print('ping()')
>     def add(self, n1, n2):
>         print('add(%d,%d)' % (n1, n2))
>         return n1 + n2
>     def calculate(self, logid, work):
>         print('calculate(%d, %r)' % (logid, work))
>         if work.op == Operation.ADD:
>             val = work.num1 + work.num2
>         elif work.op == Operation.SUBTRACT:
>             val = work.num1 - work.num2
>         elif work.op == Operation.MULTIPLY:
>             val = work.num1 * work.num2
>         elif work.op == Operation.DIVIDE:
>             if work.num2 == 0:
>                 x = InvalidOperation()
>                 x.whatOp = work.op
>                 x.why = 'Cannot divide by 0'
>                 raise x
>             val = work.num1 / work.num2
>         else:
>             x = InvalidOperation()
>             x.whatOp = work.op
>             x.why = 'Invalid operation'
>             raise x
>         log = SharedStruct()
>         log.key = logid
>         log.value = '%d' % (val)
>         self.log[logid] = log
>         return val
>     def getStruct(self, key):
>         print('getStruct(%d)' % (key))
>         return self.log[key]
>     def zip(self):
>         print('zip()')
> if __name__ == '__main__':
>     handler = CalculatorHandler()
>     processor = Calculator.Processor(handler)
>     transport = TSocket.TServerSocket(port=9090)
>     tfactory = TTransport.TBufferedTransportFactory()
>     pfactory = TBinaryProtocol.TBinaryProtocolFactory()
>     server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
>     # You could do one of these for a multithreaded server
>     # server = TServer.TThreadedServer(
>     #     processor, transport, tfactory, pfactory)
>     # server = TServer.TThreadPoolServer(
>     #     processor, transport, tfactory, pfactory)
>     print('Starting the server...')
>     server.serve()
>     print('done.')
> }}
> h4. Runtime protocol:
> h4. 
> {{
> EBIN Path : 
> D:\SoftDevelopment\Projects\erlang-and-thrift_idea\erlang-and-thrift\_build\default\lib\erlang_and_thrift\ebin
>  
> D:\SoftDevelopment\Projects\erlang-and-thrift_idea\erlang-and-thrift\_build\default\lib\jsx\ebin
>  
> D:\SoftDevelopment\Projects\erlang-and-thrift_idea\erlang-and-thrift\_build\default\lib\thrift\ebin
> ------------------------------------------
> Eshell V9.0  (abort with ^G)
> 1> client:t().
> ** exception error: no match of right hand side value {error,econnrefused}
>      in function  client:t/0 
> (d:/SoftDevelopment/Projects/erlang-and-thrift_idea/erlang-and-thrift/_build/default/lib/erlang_and_thrift/src/client.erl,
>  line 33)
> 2> Terminate batch job (Y/N)? y
> D:\SoftDevelopment\Projects\erlang-and-thrift_idea\erlang-and-thrift>tcping64 
> localhost 9090
> Probing ::1:9090/tcp - Port is open - time=0.580ms
> Probing ::1:9090/tcp - Port is open - time=0.622ms
> Probing ::1:9090/tcp - Port is open - time=1.038ms
> Probing ::1:9090/tcp - Port is open - time=1.050ms
> Ping statistics for ::1:9090
>      4 probes sent.
>      4 successful, 0 failed.
> Approximate trip times in milli-seconds:
>      Minimum = 0.580ms, Maximum = 1.050ms, Average = 0.822ms
> }}



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to