Skip to content
This repository
Browse code

fixed the socket behavior

  • Loading branch information...
commit c9992b455e756ee2b9eb32a3b979bb3966aece93 1 parent eed4d2d
Tarek Ziade tarekziade authored
23 vaurien/handlers.py
@@ -2,7 +2,8 @@
2 2
3 3
4 4 def normal(source, dest, to_backend, name, settings, server):
5   - dest.sendall(server.get_data(source))
  5 + request = server.get_data(source)
  6 + dest.sendall(request)
6 7
7 8
8 9 def delay(source, dest, to_backend, name, settings, server):
@@ -15,12 +16,22 @@ def delay(source, dest, to_backend, name, settings, server):
15 16
16 17 def errors(source, dest, to_backend, name, settings, server):
17 18 """Throw errors on the socket"""
  19 + if to_backend:
  20 + server.get_data(source)
  21 + # XXX find how to handle errors (which errors should we send)
  22 + #
  23 + # depends on the protocol
  24 + dest.sendall("YEAH")
  25 +
  26 +
  27 +def hang(source, dest, to_backend, name, settings, server):
  28 + """Reads the packets that have been sent."""
  29 + # consume the socket and hang
18 30 server.get_data(source)
19   - # XXX find how to handle errors (which errors should we send)
20   - dest.sendall("YEAH")
  31 + while True:
  32 + gevent.sleep(1.)
21 33
22 34
23 35 def blackout(source, dest, to_backend, name, settings, server):
24   - """just drop the packets that had been sent"""
25   - # consume the socket. That's it
26   - server.get_data(source)
  36 + """Don't do anything -- the sockets get closed"""
  37 + return
6 vaurien/run.py
@@ -101,7 +101,11 @@ def main():
101 101 key = key[len('vaurien.'):]
102 102 prefix = 'vaurien.'
103 103
104   - value = getattr(args, key, None)
  104 + try:
  105 + value = getattr(args, key)
  106 + except AttributeError:
  107 + value = None
  108 +
105 109 if value is not None:
106 110 settings[prefix + key] = value
107 111
53 vaurien/server.py
... ... @@ -1,3 +1,6 @@
  1 +import time
  2 +import errno
  3 +import socket
1 4 import gevent
2 5 import random
3 6
@@ -70,12 +73,22 @@ def initialize_choices(self):
70 73 self.handlers[name] = handler
71 74
72 75 def handle(self, source, address):
  76 + source.setblocking(0)
73 77 dest = create_connection(self.dest)
  78 + dest.setblocking(0)
74 79 handler_name = random.choice(self.choices)
75 80 handler = self.handlers[handler_name]
76 81 self.statsd_incr(handler_name)
77   - gevent.spawn(self.weirdify, handler, handler_name, source, dest, True)
78   - gevent.spawn(self.weirdify, handler, handler_name, dest, source, False)
  82 + try:
  83 + back = gevent.spawn(self.weirdify, handler, handler_name, source,
  84 + dest, True)
  85 + forth = gevent.spawn(self.weirdify, handler, handler_name, dest,
  86 + source, False)
  87 + back.join()
  88 + forth.join()
  89 + finally:
  90 + source.close()
  91 + dest.close()
79 92
80 93 def statsd_incr(self, counter):
81 94 if self._statsd:
@@ -91,25 +104,23 @@ def weirdify(self, handler, handler_name, source, dest, to_backend):
91 104 """
92 105 self._logger.debug('starting weirdify %s' % to_backend)
93 106 try:
94   - while self.running:
95   - # chose what we want to do.
96   - try:
97   - settings = self.settings.getsection('handler.%s' %
98   - handler_name)
99   - handler(source=source, dest=dest, to_backend=to_backend,
100   - name=handler_name, server=self, settings=settings)
101   - except ValueError:
102   - return
  107 + settings = self.settings.getsection('handlers:%s' %
  108 + handler_name)
  109 + handler(source=source, dest=dest, to_backend=to_backend,
  110 + name=handler_name, server=self, settings=settings)
103 111 finally:
104   - source.close()
105   - dest.close()
106 112 self._logger.debug('exiting weirdify %s' % to_backend)
107 113
108   - def get_data(self, source):
109   - try:
110   - data = source.recv(int(self.settings['vaurien.bufsize']))
111   - if not data:
112   - raise ValueError
113   - return data
114   - except error: # socket.error
115   - raise ValueError
  114 + def get_data(self, source, delay=.2):
  115 + bufsize = int(self.settings['vaurien.bufsize'])
  116 + data = ''
  117 + start = time.time()
  118 +
  119 + while time.time() - start < delay:
  120 + try:
  121 + data += source.recv(bufsize)
  122 + except socket.error, err:
  123 + if err.args[0] == errno.EWOULDBLOCK:
  124 + pass
  125 +
  126 + return data
13 vaurien/tests/vaurien.ini
... ... @@ -1,11 +1,4 @@
1 1 [vaurien]
2   -host = 0.0.0.0
3   -port = 8080
4   -proxied_host = 0.0.0.0
5   -proxied_port = 8888
6   -
7   -behavior = 10:delay, 80:normal
8   -
9   -[handler:delay]
10   -callable = vaurien.callables.delay
11   -handlers.delay.sleep = 10
  2 +local = 0.0.0.0:8181
  3 +distant = 0.0.0.0:8080
  4 +behavior = 100:hang
1  vaurien/util.py
... ... @@ -1,5 +1,4 @@
1 1 import sys
2   -
3 2 from gevent.socket import gethostbyname
4 3
5 4

0 comments on commit c9992b4

Konstantin

As I understand, this behaviour is suitable for REST interfaces, query-response protocols. Database connections behaves in other way, after data is send, server may ping client, but proxy is not responding properly, I think.

Please sign in to comment.
Something went wrong with that request. Please try again.