Files @ 870c5c6c334f
Branch filter:

Location: Morevna/src/netnode.py

Laman
reacquiring old locks
import os
from datetime import datetime
import socket
import logging as log

import config as conf
from networkers import NetworkReader, NetworkWriter
from hashtree import HashTree


lock_file = os.path.join(conf.directory, "dirty.lock")


class FailedConnection(Exception): pass
class LockedException(Exception): pass
class IncompatibleException(Exception): pass


class BaseConnection:  # abstract
	def __init__(self):
		self._socket = None
		self.incoming = None
		self.outcoming = None

	def create_networkers(self):
		fr = self._socket.makefile(mode="rb")
		fw = self._socket.makefile(mode="wb")

		self.incoming = NetworkReader(fr)
		self.outcoming = NetworkWriter(fw)

	def __enter__(self):
		return self.incoming, self.outcoming

	def __exit__(self, exc_type, exc_val, exc_tb):
		try:
			self._socket.shutdown(socket.SHUT_RDWR)
			self._socket.close()
		except OSError:
			log.warning("broken connection")


class NetNode:
	def __init__(self, filename, tree_file=""):
		self._incoming = None
		self._outcoming = None

		self._filename = filename
		self._tree_file = tree_file

		if tree_file:
			self._tree = HashTree.load(tree_file)
		else:
			self._tree = HashTree.from_file(filename)

		self._new_leaves = dict()

	def is_locked(self):
		return os.path.isfile(lock_file)

	def _lock(self):
		try:
			f = open(lock_file, "x")
			f.close()
		except FileExistsError:
			stat = os.stat(lock_file)
			dt = datetime.now().timestamp()-stat.st_mtime
			if dt<5*60:
				raise LockedException()
			log.warning("Found an old lock file ({0}s), ignoring it.".format(round(dt)))
			self._refresh_lock()

	def _refresh_lock(self):
		os.utime(lock_file)

	def _unlock(self):
		os.remove(lock_file)

	def _update_tree(self):
		log.info("updating hash tree...")
		self._tree.batch_update(self._new_leaves.items())
		self._tree.save(self._tree_file)
		self._new_leaves = dict()
		log.info("tree updated")