forked from sagemath/sagecell
-
Notifications
You must be signed in to change notification settings - Fork 0
/
db.py
168 lines (135 loc) · 5.14 KB
/
db.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
"""
Generic Database Adapter
------------------------
The database is where information that needs to be accessed
by different pieces of the backend is stored. This includes
the code inside each executed cell, and the output messages
produced when the code is run.
There are several different classes that extend the
:class:`DB` class in order to allow for a choice of
the database used.
"""
class DB(object):
"""
Abstract base class for database adaptors.
"""
def __init__(self):
raise NotImplementedError
def new_input_message(self, msg):
"""
Add a new computation request to the database to be retrieved
by :meth:`get_input_messages`.
:arg dict msg: the IPython-style message containing a new
string of code to execute
"""
raise NotImplementedError
def get_input_messages(self, device, limit=None):
"""
Find the computations that haven't been started yet,
mark them as in-progress with the device ID and return
the cells. The :obj:`limit` keyword can give an upper
on the number of unassigned sessions returned.
The database also stores a list of sessions for each device.
Currently, we rely on each message having a device attribute
that is set, if possible, when the message is created. Another
possibility is to just have the device query the sessions table to
return the sessions that are currently active. I'm not sure which is
faster.
:arg str device_id: the ID of the device
:arg int limit: the maximum number of computations to retrieve
:returns: a list of cells
:rtype: list
"""
raise NotImplementedError
def get_input_message_by_shortened(self, shortened):
"""
Retrieve the input code for a shortened field
:arg str shortened: the shortened identifier for the input message
:returns: a string containing the input code, or the empty string if
the shortened ID does not match any input.
:rtype: str
"""
raise NotImplementedError
def add_messages(self, messages):
"""
Add IPython-style output messages to the database.
:arg list output: the messages to add
"""
raise NotImplementedError
def register_device(self, device, account, workers, pgid):
"""
Register a device with the database
We store the pgid so that we can later kill the device and all
subprocesses by sshing into the account (if set) and doing::
import os, signal
os.kill(pgid, signal.SIGKILL) #or signal.SIGTERM to be nicer about it
:arg str device: device ID
:arg str account: account
:arg int workers: number of workers
:arg int pgid: process group ID
"""
raise NotImplementedError
def delete_device(self, device):
"""
Delete a device from the database
:arg str device: device ID
"""
raise NotImplementedError
def get_devices(self):
"""
:returns: currently registered devices
:rtype: list
"""
raise NotImplementedError
def get_messages(self, session, sequence=0):
"""
Get the messages from some session, starting with
the message with sequence number ``sequence``.
:arg str session: the session ID
:arg int sequence: the minimum sequence in the returned messages
:returns: a list of IPython-style messages
"""
raise NotImplementedError
def close_session(self, device, session):
u"""
Delete a session-to-device mapping.
:arg str device: the ID of the device
:arg str session: the ID of the session
"""
raise NotImplementedError
def create_secret(self, session):
"""
Generate a new :mod:`hmac` object and associate it
with the session. Used only with "untrusted" database
adaptors. (See :ref:`trusted`.)
:arg str session: the ID of the new session
"""
raise NotImplementedError
def set_ipython_ports(self, kernel):
"""
Set the ports with which an IPython kernel can communicate
with another process. Used only with the IPython device.
:arg tuple kernel: the ports used by the IPython kernel
"""
raise NotImplementedError
def get_ipython_port(self, channel):
"""
Get a port with which an IPython kernel can communicate
with another process. Used only with the IPython device.
:arg str channel: IPython channel name (``"pid"``, ``"xreq"``,
``"sub"``, or ``"rep"``)
:returns: port number
:rtype: int
"""
raise NotImplementedError
def new_context(self):
"""
Reconnect to the database. This function should be
called before the first database access in each new process.
"""
def new_context_copy(self):
"""
Create a copy of this object for use in a single thread.
:returns: a new database object
:rtype: DB
"""