1515class NonBlockingLease (object ):
1616 """Exclusive lease that does not block.
1717
18- An exclusive lease ensures that only one client at a time owns the lease. The client may
19- renew the lease without losing it by obtaining a new lease with the same path and same
20- identity. The lease object evaluates to True if the lease was obtained.
18+ An exclusive lease ensures that only one client at a time owns the lease.
19+ The client may renew the lease without losing it by obtaining a new lease
20+ with the same path and same identity. The lease object evaluates to True
21+ if the lease was obtained.
2122
22- A common use case is a situation where a task should only run on a single host. In this
23- case, the clients that did not obtain the lease should exit without performing the protected
24- task.
23+ A common use case is a situation where a task should only run on a single
24+ host. In this case, the clients that did not obtain the lease should exit
25+ without performing the protected task.
2526
26- The lease stores time stamps using client clocks, and will therefore only work if client clocks
27- are roughly synchronised. It uses UTC, and works across time zones and daylight savings.
27+ The lease stores time stamps using client clocks, and will therefore only
28+ work if client clocks are roughly synchronised. It uses UTC, and works
29+ across time zones and daylight savings.
2830
2931 Example usage: with a :class:`~kazoo.client.KazooClient` instance::
3032
3133 zk = KazooClient()
3234 zk.start()
33- # Hold lease over an hour in order to keep job on same machine, with failover if it dies.
34- lease = zk.NonBlockingLease("/db_leases/hourly_cleanup", datetime.timedelta(minutes = 70),
35- identifier = "DB hourly cleanup on " + socket.gethostname())
35+ # Hold lease over an hour in order to keep job on same machine,
36+ # with failover if it dies.
37+ lease = zk.NonBlockingLease(
38+ "/db_leases/hourly_cleanup", datetime.timedelta(minutes = 70),
39+ identifier = "DB hourly cleanup on " + socket.gethostname())
3640 if lease:
3741 do_hourly_database_cleanup()
3842 """
@@ -42,15 +46,20 @@ class NonBlockingLease(object):
4246 _date_format = "%Y-%m-%dT%H:%M:%S"
4347 _byte_encoding = 'utf-8'
4448
45- def __init__ (self , client , path , duration , identifier = None , utcnow = datetime .datetime .utcnow ):
49+ def __init__ (self , client , path , duration , identifier = None ,
50+ utcnow = datetime .datetime .utcnow ):
4651 """Create a non-blocking lease.
4752
4853 :param client: A :class:`~kazoo.client.KazooClient` instance.
4954 :param path: The lease path to use.
50- :param duration: Duration during which the lease is reserved. A :class:`~datetime.timedelta` instance.
51- :param identifier: Unique name to use for this lease holder. Reuse in order to renew the lease.
52- Defaults do :meth:`socket.gethostname()`.
53- :param utcnow: Clock function, by default returning :meth:`datetime.datetime.utcnow()`. Used for testing.
55+ :param duration: Duration during which the lease is reserved. A
56+ :class:`~datetime.timedelta` instance.
57+ :param identifier: Unique name to use for this lease holder. Reuse in
58+ order to renew the lease. Defaults to
59+ :meth:`socket.gethostname()`.
60+ :param utcnow: Clock function, by default returning
61+ :meth:`datetime.datetime.utcnow()`. Used for testing.
62+
5463 """
5564 ident = identifier or socket .gethostname ()
5665 self .obtained = False
@@ -69,13 +78,15 @@ def _attempt_obtaining(self, client, path, duration, ident, utcnow):
6978 if data ["version" ] != self ._version :
7079 # We need an upgrade, let someone else take the lease
7180 return
72- current_end = datetime .datetime .strptime (data ['end' ], self ._date_format )
81+ current_end = datetime .datetime .strptime (data ['end' ],
82+ self ._date_format )
7383 if data ['holder' ] != ident and now < current_end :
7484 # Another client is still holding the lease
7585 return
7686 client .delete (holder_path )
7787 end_lease = (now + duration ).strftime (self ._date_format )
78- new_data = {'version' : self ._version , 'holder' : ident , 'end' : end_lease }
88+ new_data = {'version' : self ._version , 'holder' : ident ,
89+ 'end' : end_lease }
7990 client .create (holder_path , self ._encode (new_data ))
8091 self .obtained = True
8192
@@ -100,16 +111,21 @@ def __bool__(self):
100111class MultiNonBlockingLease (object ):
101112 """Exclusive lease for multiple clients.
102113
103- This type of lease is useful when a limited set of hosts should run a particular task.
104- It will attempt to obtain leases trying a sequence of ZooKeeper lease paths.
114+ This type of lease is useful when a limited set of hosts should run a
115+ particular task. It will attempt to obtain leases trying a sequence of
116+ ZooKeeper lease paths.
105117
106118 :param client: A :class:`~kazoo.client.KazooClient` instance.
107119 :param count: Number of host leases allowed.
108120 :param path: ZooKeeper path under which lease files are stored.
109- :param duration: Duration during which the lease is reserved. A :class:`~datetime.timedelta` instance.
110- :param identifier: Unique name to use for this lease holder. Reuse in order to renew the lease.
121+ :param duration: Duration during which the lease is reserved. A
122+ :class:`~datetime.timedelta` instance.
123+ :param identifier: Unique name to use for this lease holder. Reuse in order
124+ to renew the lease.
111125 Defaults do :meth:`socket.gethostname()`.
112- :param utcnow: Clock function, by default returning :meth:`datetime.datetime.utcnow()`. Used for testing.
126+ :param utcnow: Clock function, by default returning
127+ :meth:`datetime.datetime.utcnow()`. Used for testing.
128+
113129 """
114130
115131 def __init__ (self , client , count , path , duration , identifier = None ,
0 commit comments