Repository: dask/distributed

Issue:
Cross platform workers not able to connect 
I need to have a set of win32 workers, which I am using a virtual machine to host. It seems that, even though network connectivity is fine, when you run a scheduler on a linux host and try to connect to it from a windows worker the connection cannot be resolved - worker just hangs on "Waiting to connect to:"

Any thoughts?



Discussion:
Furthermore a traceback when starting the scheduler in windows:

```
distributed.utils - ERROR - unpack requires a bytes object of length 4
Traceback (most recent call last):
  File "C:\Users\IEUser\Anaconda3\lib\site-packages\distributed\utils.py", line 237, in log_errors
    yield
  File "C:\Users\IEUser\Anaconda3\lib\site-packages\distributed\bokeh\tasks\server_lifecycle.py", line 45, in task_events
    msgs = yield read(stream)
  File "C:\Users\IEUser\Anaconda3\lib\site-packages\tornado\gen.py", line 1008, in run
    value = future.result()
  File "C:\Users\IEUser\Anaconda3\lib\site-packages\tornado\concurrent.py", line 232, in result
    raise_exc_info(self._exc_info)
  File "<string>", line 3, in raise_exc_info
  File "C:\Users\IEUser\Anaconda3\lib\site-packages\tornado\gen.py", line 1017, in run
    yielded = self.gen.send(value)
  File "C:\Users\IEUser\Anaconda3\lib\site-packages\distributed\core.py", line 222, in read
    n_frames = struct.unpack('L', n_frames)[0]
struct.error: unpack requires a bytes object of length 4
distributed.utils - ERROR - unpack requires a bytes object of length 4
Traceback (most recent call last):
  File "C:\Users\IEUser\Anaconda3\lib\site-packages\distributed\utils.py", line 237, in log_errors
    yield
  File "C:\Users\IEUser\Anaconda3\lib\site-packages\distributed\bokeh\status\server_lifecycle.py", line 71, in progress
    msg = yield read(stream)
  File "C:\Users\IEUser\Anaconda3\lib\site-packages\tornado\gen.py", line 1008, in run
    value = future.result()
  File "C:\Users\IEUser\Anaconda3\lib\site-packages\tornado\concurrent.py", line 232, in result
    raise_exc_info(self._exc_info)
  File "<string>", line 3, in raise_exc_info
  File "C:\Users\IEUser\Anaconda3\lib\site-packages\tornado\gen.py", line 1017, in run
    yielded = self.gen.send(value)
  File "C:\Users\IEUser\Anaconda3\lib\site-packages\distributed\core.py", line 222, in read
    n_frames = struct.unpack('L', n_frames)[0]
struct.error: unpack requires a bytes object of length 4

Interrupted, shutting down

```

Looks like the `struct` datatype conventions are platform specific.  We currently incorrectly assume that unsigned longs are eight bytes long.   Should be a quick fix.  


Resolving patch:
diff --git a/distributed/core.py b/distributed/core.py
--- a/distributed/core.py
+++ b/distributed/core.py
@@ -219,10 +219,10 @@ def read(stream):
         raise Return(msg)
     else:
         n_frames = yield stream.read_bytes(8)
-        n_frames = struct.unpack('L', n_frames)[0]
+        n_frames = struct.unpack('Q', n_frames)[0]
 
         lengths = yield stream.read_bytes(8 * n_frames)
-        lengths = struct.unpack('L' * n_frames, lengths)
+        lengths = struct.unpack('Q' * n_frames, lengths)
 
         frames = []
         for length in lengths:
@@ -249,8 +249,8 @@ def write(stream, msg):
             logger.exception(e)
             raise
 
-        lengths = ([struct.pack('L', len(frames))] +
-                   [struct.pack('L', len(frame)) for frame in frames])
+        lengths = ([struct.pack('Q', len(frames))] +
+                   [struct.pack('Q', len(frame)) for frame in frames])
         yield stream.write(b''.join(lengths))
 
         for frame in frames:


Test patch: