[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r22489: {weather} Be a good Weather and reconnect if the local Tor instance is (in weather/trunk: . lib/weather)
Author: kaner
Date: 2010-06-07 17:26:07 +0000 (Mon, 07 Jun 2010)
New Revision: 22489
Modified:
weather/trunk/Weather.py
weather/trunk/lib/weather/poller.py
weather/trunk/lib/weather/torping.py
Log:
Be a good Weather and reconnect if the local Tor instance is offline, maybe because of some weasels
Modified: weather/trunk/Weather.py
===================================================================
--- weather/trunk/Weather.py 2010-06-07 17:21:11 UTC (rev 22488)
+++ weather/trunk/Weather.py 2010-06-07 17:26:07 UTC (rev 22489)
@@ -15,7 +15,6 @@
from twisted.internet import reactor
from twisted.internet.task import LoopingCall
-from weather.torping import TorPing
import weather.constants as constants
import weather.queries as queries
from weather.poller import WeatherPoller
@@ -265,9 +264,7 @@
# Set up database connection
dbConn = utils.setupDBConn(config.databaseName)
# Set up polling timer
- # XXX Have one main TorPing instance until TotCtl fixes its thread leak
- torPing = TorPing()
- weatherPoller = WeatherPoller(dbConn, torPing)
+ weatherPoller = WeatherPoller(dbConn)
pollTimer = LoopingCall(weatherPoller.poller)
pollTimer.start(config.pollPeriod)
# Set up webserver
Modified: weather/trunk/lib/weather/poller.py
===================================================================
--- weather/trunk/lib/weather/poller.py 2010-06-07 17:21:11 UTC (rev 22488)
+++ weather/trunk/lib/weather/poller.py 2010-06-07 17:26:07 UTC (rev 22489)
@@ -7,16 +7,16 @@
import smtplib
from twisted.web import server
-from weather.torping import TorPing
+import weather.torping as torping
import weather.config as config
import weather.constants as constants
import weather.queries as queries
import weather.utils as utils
class WeatherPoller():
- def __init__(self, dbConn, torPing):
+ def __init__(self, dbConn):
self.dbConn = dbConn
- self.torPing = torPing
+ self.torPing = torping.TorPing()
def poller(self):
self._checkAll()
@@ -25,26 +25,41 @@
def _checkAll(self):
dbQuery = queries.GETALL_SUBS_Q
self.dbConn.runQuery(dbQuery).addCallback(
- self._checkRet).addErrback(
+ self._checkHosts).addErrback(
self._errBack)
- def _checkRet(self, resultList):
+ def _checkHosts(self, resultList):
# Loop through result list and check each node
for result in resultList:
+ if not self.torPing.isConnected():
+ logging.error("Not connected to Tor, leaving loop")
+ break
checkHost = result[2]
- if not self._checkHost(checkHost):
+ ret = self._checkHost(checkHost)
+ if ret is torping.TORPING_OFFLINE:
logging.info("Server %s seems to be offline" % checkHost)
self._handleOfflineNode(result)
- else:
+ elif ret == torping.TORPING_ONLINE:
logging.info("Server %s is ok" % checkHost)
# Reset possible seen_down counter
self._resetSeendown(result)
+ else:
+ logging.error("General error while checking %s" % checkHost)
+
+ # Try to reconnect..
+ if not self.torPing.isConnected():
+ logging.error("Trying to reconnect to local Tor instance..")
+ del self.torPing
+ self.torPing = torping.TorPing()
def _errBack(self, failure):
logging.error("Error: %s" % failure.getErrorMessage())
def _checkHost(self, hostID):
- return self.torPing.ping(hostID)
+ if self.torPing.isConnected():
+ return self.torPing.ping(hostID)
+ else:
+ return torping.GENERR
def _handleOfflineNode(self, dbRow):
self._getDowntimes(dbRow[0])
Modified: weather/trunk/lib/weather/torping.py
===================================================================
--- weather/trunk/lib/weather/torping.py 2010-06-07 17:21:11 UTC (rev 22488)
+++ weather/trunk/lib/weather/torping.py 2010-06-07 17:26:07 UTC (rev 22489)
@@ -12,43 +12,58 @@
debugfile = open("debug", "w")
+TORPING_ONLINE = 0
+TORPING_OFFLINE = 1
+TORPING_GENERR = 2
+
class TorPing:
"Check to see if various tor nodes respond to SSL hanshakes"
def __init__(self, control_host = "127.0.0.1", control_port = 9051):
"Keep the connection to the control port lying around"
+ self.connected = False
+ self.control = None
self.control_host = control_host
self.control_port = control_port
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
self.sock.connect((control_host,control_port))
+ self.control = TorCtl.Connection(self.sock)
+ self.control.authenticate(weather.config.authenticator)
+ self.control.debug(debugfile)
+ self.connected = True
except:
errormsg = "Could not connect to Tor control port" + \
"Is Tor running on %s with its control port opened on %s?" \
% (control_host, control_port)
logging.error(errormsg)
- print >> sys.stderr, errormsg
- raise
- self.control = TorCtl.Connection(self.sock)
- self.control.authenticate(weather.config.authenticator)
- self.control.debug(debugfile)
def __del__(self):
- self.sock.close()
- del self.sock
- self.sock = None # prevents double deletion exceptions
+ if self.sock is not None:
+ self.sock.close()
+ del self.sock
+ self.sock = None # prevents double deletion exceptions
- # it would be better to fix TorCtl!
- try:
- self.control.close()
- except:
- logging.error("Exception while closing TorCtl")
- pass
+ if self.control is not None:
+ # it would be better to fix TorCtl!
+ try:
+ self.control.close()
+ except:
+ logging.error("Exception while closing TorCtl")
+ pass
- del self.control
- self.control = None
+ del self.control
+ self.control = None
+ def isConnected(self):
+ return self.connected
+
def ping(self, nodeId):
- "Let's see if this tor node is up by only asking Tor."
+ """Let's see if this tor node is up by only asking Tor."""
+
+ # If we're not connected (yet) to Tor, don't even try to ping
+ if not self.connected:
+ return TORPING_GENERR
+
try:
info = self.control.get_info(str("ns/id/" + nodeId))
except TorCtl.ErrorReply, e:
@@ -56,11 +71,12 @@
# ErrorReply: 552 Unrecognized key "ns/id/46D9..."
# This means that the node isn't recognized by
logging.error("ErrorReply: %s" % str(e))
- return False
+ return TORPING_OFFLINE
except:
logging.error("Unknown exception in ping()")
- return False
+ self.connected = False
+ return TORPING_GENERR
# If we're here, we were able to fetch information about the router
- return True
+ return TORPING_ONLINE