dibbler-2.py

text/x-python dibbler-2.py — 2 KB

Contenu du fichier

#!/usr/bin/python
import os, sys, select, time, random

root = 'dibbler.dir'
tmpfile = 'dibbler.tmp'
count = 100
dirfudge = 0.2
delay = 1
timeout = 10

if not os.path.isdir(root):
	os.mkdir(root)
if os.listdir(root):
	print "Warning : %s not empty"%repr(root)

class client:
	def __init__(self, client_program):
		self.fd = os.pipe()
		self.pid = os.fork()
		self.client_program = client_program
		if self.pid:
			os.close(self.fd[1])
			self.buffer = ""
			self.expected = 1
			self.score = 0
		else:
			os.dup2(self.fd[1],1)
			os.close(self.fd[0])
			os.close(self.fd[1])
			log("Starting client %s..."%repr(client_program))
			os.execlp(client_program, client_program, root)
	def err(self, msg, line=""):
		log("%s from %s - %s"%(msg, self.client_program, line))
	def fileno(self):
		return self.fd[0]
	def handle_read(self): 
		self.buffer += os.read(self.fd[0], 1024)
		while "\n" in self.buffer:
			line, self.buffer = self.buffer.split("\n", 1)
			line = line.strip()
			if ":" not in line:
				self.err("Discarding invalid line", line)
				continue
			index, value = line.split(":", 1)
			if not index.isdigit():
				self.err("Invalid index", line)
				continue
			index = int(index)
			if index<self.expected:
				self.err("Low index", line)
				continue
			self.expected = index
			if index not in pebbles:
				self.err("Early value", line)
				continue
			if pebbles[index] != value:
				self.err("Invalid value (expected %s)"%pebbles[index], line)
				continue
			self.score += 1
			log("Valid data from %s (i=%s, score=%s)"%(self.client_program, index, self.score))

def log(msg):
	print >>sys.stderr, msg

def check_clients(deadline):
	while time.time() < deadline:
		rfds, wfds, efds = select.select(clients, [], [], max(deadline-time.time(),0))
		for client in rfds:
			client.handle_read()

def make_directory():
	rootdir = random.choice(dirs)
	dirname = "%f"%random.random()
	dirpath = os.path.join(rootdir, dirname)
	try:
		log("Creating directory : %s"%repr(dirpath))
		os.mkdir(dirpath)
		dirs.append(dirpath)
	except:
		print "Could not make "+repr(dirname)

def make_pebble(i):
	rootdir = random.choice(dirs)
	filename = str(i)
	filepath = os.path.join(rootdir, filename)
	value = "%03d"%random.randint(0,999)
	log("Creating file : %s (data : %s)"%(repr(filepath), value))
	f = open(tmpfile,"w")
	f.write(value)
	f.close()
	pebbles[i]=value
	os.rename(tmpfile, filepath)

i = 1
pebbles = {}
dirs = [root]
clients = []
for arg in sys.argv[1:]:
	clients.append(client(arg))
next = time.time()
while i<count:
	check_clients(next)
	if random.random()<dirfudge:
		make_directory()
	else:
		make_pebble(i)
		i += 1
	next += delay
next += timeout
log("Waiting %d second(s) before exitting..."%timeout)
check_clients(next)

	
for c in clients:
	print c.client_program, c.score