On Thu, Sep 7, 2017 at 12:32 PM Amit Saha <[email protected]> wrote:

> On Wed, Sep 6, 2017 at 6:26 PM Amit Saha <[email protected]> wrote:
>
>> On Wed, 6 Sep 2017 at 5:40 am, Ken Payson <[email protected]> wrote:
>>
>>> On Tue, Sep 5, 2017 at 6:07 AM, Amit Saha <[email protected]> wrote:
>>>
>>>>
>>>>
>>>> On Tue, Sep 5, 2017 at 9:02 AM Amit Saha <[email protected]> wrote:
>>>>
>>>>> On Tue, 5 Sep 2017 at 6:44 am, Ken Payson <[email protected]> wrote:
>>>>>
>>>>>> gRPC Python sets the SO_REUSEADDR option on server sockets, which
>>>>>> allows multiple servers to bind to the same port.
>>>>>>
>>>>>
>>>>> Thanks. Is there any reason why this is set to be the default behavior?
>>>>>
>>>>
>>>> Searching around, I can see that this *may* be desired behavior and
>>>> hence gRPC has made a pragmatic choice. However, it seems to be most useful
>>>> in a scenario where an existing socket is in the TIME_WAIT state and we
>>>> want a new server process to bind to the same addr/port. However, two
>>>> questions:
>>>>
>>>
>>>> 1. This is not the case here - both of my servers are in LISTEN
>>>>
>>> I think you are referring to the SO_REUSEPORT option.  The SO_REUSEADDR
>>> is different, and is intended for having multiple processes bind to the
>>> same port.  One advantage of this is that you can scale by having multiple
>>> processes serving requests.
>>>
>>
>> Sorry, but whatever I read seems to suggest the behavior you mention for
>> SO_REUSEPORT and not SO_REUSEADDR. I will definitely look more, but if you
>> have a handy reference you can share, that will be great.
>>
>
> I switched to Linux for my experiments this time. Let's consider the
> server below:
>
> import socket
> import os
>
> def start_server():
>     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
>     sock.bind(('localhost', 5555))
>     sock.listen(0)
>
>     while True:
>         connection, address = sock.accept()
>         buf = connection.recv(64)
>         if len(buf) > 0:
>            print os.getpid()
>
>
> if __name__ == '__main__':
>     start_server()
>
> Start the instance 1:
>
> $ lsof -i TCP:5555
> COMMAND   PID  USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
> python  10973 asaha    3u  IPv4 11332922      0t0  TCP localhost:5555
> (LISTEN)
>
>
> If I try to start a second instance of the server, I get:
>
> Traceback (most recent call last):
>   File "server.py", line 19, in <module>
>     start_server()
>   File "server.py", line 7, in start_server
>     sock.bind(('localhost', 5555))
>   File "/usr/lib/python2.7/socket.py", line 228, in meth
>     return getattr(self._sock,name)(*args)
> socket.error: [Errno 98] Address already in use
>
> Now if I change the server as follows to use SO_REUSEPORT:
>
> import socket
> import os
>
>
> def start_server():
>     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
>     sock.bind(('localhost', 5555))
>     sock.listen(0)
>
>     while True:
>         connection, address = sock.accept()
>         buf = connection.recv(64)
>         if len(buf) > 0:
>             print os.getpid()
>
>
> if __name__ == '__main__':
>     start_server()
>
>
> I can start two server processes and I see both instances serving client
> requests. So that tells me that SO_REUSEADDR doesn't allow a seond process
> to LISTEN when another already is.
>
> Now, let's get back to my original gRPC server. When I try to start a
> second instance of the server, I get this on Linux:
>
> E0907 12:28:57.205046525   16071 server_chttp2.c:53]
> {"created":"@1504751337.205028841","description":"No address added out of
> total 1
> resolved","file":"src/core/ext/transport/chttp2/server/chttp2_server.c","file_line":260,"referenced_errors":[{"created":"@1504751337.205026361","description":"Unable
> to configure
> socket","fd":3,"file":"src/core/lib/iomgr/tcp_server_utils_posix_common.c","file_line":215,"referenced_errors":[{"created":"@1504751337.205023798","description":"OS
> Error","errno":98,"file":"src/core/lib/iomgr/tcp_server_utils_posix_common.c","file_line":188,"os_error":"Address
> already in use","syscall":"bind"}]}]}
>
> Much better, this exactly what I expected. So, this tells me that the
> behaviour of SO_REUSEADDR is "different" on OS X?
>

Only for gRPC's Python server i.e. (since I *did* get the error with my
above serve file on OSX).



>
> FWIW, I found https://github.com/veithen/knetstat useful to be able to
> see the socket options set.
>
>
>>>>>>>

-- 
You received this message because you are subscribed to the Google Groups 
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/grpc-io.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/grpc-io/CANODV3kyWr6_fjpFNgW89xnxFtyNWLyKYnC0icFZe5nCjvEGPw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to