Skip to content

Instantly share code, notes, and snippets.

@cybojanek
Created April 2, 2013 02:08
Show Gist options
  • Save cybojanek/5289423 to your computer and use it in GitHub Desktop.
Save cybojanek/5289423 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor
from twisted.protocols.basic import LineReceiver
from uuid import uuid1 as uuid
import time
START_CHUNK_SIZE = 10 ** 6
import redis
r = redis.StrictRedis(host='localhost', port=6379, db=1)
if not r.get('counter'):
print "INITIZIALING"
r.set('counter', 0)
r.set('seconds', 60)
r.delete('assigned')
r.delete('clients')
r.delete('best')
def now_time():
return int(time.time())
def seconds_between_updates():
return float(r.get('seconds'))
def add_min_result(length, string):
best = r.zrange('best', 0, 0)
if len(best) == 0:
r.zadd('best', length, string)
else:
score = int(r.zscore('best', best[0]))
if length < score:
r.zadd('best', length, string)
def add_assigned_chunk(start, size):
r.zadd('assigned', start, size)
def done_with_chunk(start):
r.zrem('assigned', start)
def get_next_client_block(client_id):
client = r.hgetall('c:%s' % client_id)
if not client:
return
now = now_time()
elapsed = now - int(client['last_update'])
if elapsed == 0:
elapsed = 1
next_chunk_size = int(float(client['chunk_size']) / float(elapsed) * seconds_between_updates())
start = increment_counter(next_chunk_size)
r.hmset('c:%s' % client_id, {'last_update': now, 'chunk_size': next_chunk_size, 'last_chunk': start})
return '%s %s' % (start, next_chunk_size)
def increment_counter(chunk_size):
start = r.incr('counter', chunk_size) - chunk_size
return start
def make_new_client():
client_id = uuid()
now = now_time()
client_chunk_size = START_CHUNK_SIZE
start = increment_counter(client_chunk_size)
add_assigned_chunk(start, client_chunk_size)
r.sadd('clients', client_id)
r.hmset('c:%s' % client_id, {'last_update': now, 'chunk_size': client_chunk_size, 'last_chunk': start})
return " ".join([str(x) for x in client_id, start, client_chunk_size])
### Protocol Implementation
class BlockAssigner(LineReceiver):
def lineReceived(self, line):
print "LINE: %r" % line
# Empty message: new client
if len(line) == 0:
s = make_new_client()
print "NEW CLIENT: %r" % (s)
self.sendLine(s)
return
client_id, start, best_len, best_str = line.split(' ')
add_min_result(int(best_len), best_str)
done_with_chunk(int(start))
self.sendLine(get_next_client_block(client_id))
def main():
f = Factory()
f.protocol = BlockAssigner
reactor.listenTCP(8000, f)
reactor.run()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment