~divmod-dev/divmod.org/trunk

« back to all changes in this revision

Viewing changes to Epsilon/epsilon/hotfixes/delayedcall_seconds.py

  • Committer: Jean-Paul Calderone
  • Date: 2014-06-29 20:33:04 UTC
  • mfrom: (2749.1.1 remove-epsilon-1325289)
  • Revision ID: exarkun@twistedmatrix.com-20140629203304-gdkmbwl1suei4m97
mergeĀ lp:~exarkun/divmod.org/remove-epsilon-1325289

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
import traceback
3
 
 
4
 
from zope.interface import implements
5
 
 
6
 
from twisted.persisted import styles
7
 
from twisted.internet.interfaces import IDelayedCall
8
 
from twisted.internet import error, base
9
 
from twisted.python import reflect
10
 
 
11
 
class DelayedCall(styles.Ephemeral):
12
 
 
13
 
    implements(IDelayedCall)
14
 
    # enable .debug to record creator call stack, and it will be logged if
15
 
    # an exception occurs while the function is being run
16
 
    debug = False
17
 
    _str = None
18
 
 
19
 
    def __init__(self, time, func, args, kw, cancel, reset, seconds=None):
20
 
        self.time, self.func, self.args, self.kw = time, func, args, kw
21
 
        self.resetter = reset
22
 
        self.canceller = cancel
23
 
        self.seconds = seconds
24
 
        self.cancelled = self.called = 0
25
 
        self.delayed_time = 0
26
 
        if self.debug:
27
 
            self.creator = traceback.format_stack()[:-2]
28
 
 
29
 
    def getTime(self):
30
 
        """Return the time at which this call will fire
31
 
 
32
 
        @rtype: C{float}
33
 
        @return: The number of seconds after the epoch at which this call is
34
 
        scheduled to be made.
35
 
        """
36
 
        return self.time + self.delayed_time
37
 
 
38
 
    def cancel(self):
39
 
        """Unschedule this call
40
 
 
41
 
        @raise AlreadyCancelled: Raised if this call has already been
42
 
        unscheduled.
43
 
 
44
 
        @raise AlreadyCalled: Raised if this call has already been made.
45
 
        """
46
 
        if self.cancelled:
47
 
            raise error.AlreadyCancelled
48
 
        elif self.called:
49
 
            raise error.AlreadyCalled
50
 
        else:
51
 
            self.canceller(self)
52
 
            self.cancelled = 1
53
 
            if self.debug:
54
 
                self._str = str(self)
55
 
            del self.func, self.args, self.kw
56
 
 
57
 
    def reset(self, secondsFromNow):
58
 
        """Reschedule this call for a different time
59
 
 
60
 
        @type secondsFromNow: C{float}
61
 
        @param secondsFromNow: The number of seconds from the time of the
62
 
        C{reset} call at which this call will be scheduled.
63
 
 
64
 
        @raise AlreadyCancelled: Raised if this call has been cancelled.
65
 
        @raise AlreadyCalled: Raised if this call has already been made.
66
 
        """
67
 
        if self.cancelled:
68
 
            raise error.AlreadyCancelled
69
 
        elif self.called:
70
 
            raise error.AlreadyCalled
71
 
        else:
72
 
            if self.seconds is None:
73
 
                new_time = base.seconds() + secondsFromNow
74
 
            else:
75
 
                new_time = self.seconds() + secondsFromNow
76
 
            if new_time < self.time:
77
 
                self.delayed_time = 0
78
 
                self.time = new_time
79
 
                self.resetter(self)
80
 
            else:
81
 
                self.delayed_time = new_time - self.time
82
 
 
83
 
    def delay(self, secondsLater):
84
 
        """Reschedule this call for a later time
85
 
 
86
 
        @type secondsLater: C{float}
87
 
        @param secondsLater: The number of seconds after the originally
88
 
        scheduled time for which to reschedule this call.
89
 
 
90
 
        @raise AlreadyCancelled: Raised if this call has been cancelled.
91
 
        @raise AlreadyCalled: Raised if this call has already been made.
92
 
        """
93
 
        if self.cancelled:
94
 
            raise error.AlreadyCancelled
95
 
        elif self.called:
96
 
            raise error.AlreadyCalled
97
 
        else:
98
 
            self.delayed_time += secondsLater
99
 
            if self.delayed_time < 0:
100
 
                self.activate_delay()
101
 
                self.resetter(self)
102
 
 
103
 
    def activate_delay(self):
104
 
        self.time += self.delayed_time
105
 
        self.delayed_time = 0
106
 
 
107
 
    def active(self):
108
 
        """Determine whether this call is still pending
109
 
 
110
 
        @rtype: C{bool}
111
 
        @return: True if this call has not yet been made or cancelled,
112
 
        False otherwise.
113
 
        """
114
 
        return not (self.cancelled or self.called)
115
 
 
116
 
    def __le__(self, other):
117
 
        return self.time <= other.time
118
 
 
119
 
    def __str__(self):
120
 
        if self._str is not None:
121
 
            return self._str
122
 
        if hasattr(self, 'func'):
123
 
            if hasattr(self.func, 'func_name'):
124
 
                func = self.func.func_name
125
 
                if hasattr(self.func, 'im_class'):
126
 
                    func = self.func.im_class.__name__ + '.' + func
127
 
            else:
128
 
                func = reflect.safe_repr(self.func)
129
 
        else:
130
 
            func = None
131
 
 
132
 
        if self.seconds is None:
133
 
            now = base.seconds()
134
 
        else:
135
 
            now = self.seconds()
136
 
        L = ["<DelayedCall %s [%ss] called=%s cancelled=%s" % (
137
 
                id(self), self.time - now, self.called, self.cancelled)]
138
 
        if func is not None:
139
 
            L.extend((" ", func, "("))
140
 
            if self.args:
141
 
                L.append(", ".join([reflect.safe_repr(e) for e in self.args]))
142
 
                if self.kw:
143
 
                    L.append(", ")
144
 
            if self.kw:
145
 
                L.append(", ".join(['%s=%s' % (k, reflect.safe_repr(v)) for (k, v) in self.kw.iteritems()]))
146
 
            L.append(")")
147
 
 
148
 
        if self.debug:
149
 
            L.append("\n\ntraceback at creation: \n\n%s" % ('    '.join(self.creator)))
150
 
        L.append('>')
151
 
 
152
 
        return "".join(L)
153
 
 
154
 
 
155
 
def install():
156
 
    global DelayedCall
157
 
 
158
 
    base.DelayedCall.__dict__ = DelayedCall.__dict__
159
 
    base.DelayedCall.__dict__['__module__'] = 'twisted.internet.base'
160
 
    DelayedCall = base.DelayedCall