@@ -14,52 +14,60 @@ local queue_session = {}
14
14
-- Replicaset mode switch.
15
15
--
16
16
-- Running a queue in master-replica mode requires that
17
- -- `_queue_inactive_sessions ` space was not temporary.
17
+ -- `_queue_shared_sessions ` space was not temporary.
18
18
-- When the queue is running in single mode,
19
19
-- the space is converted to temporary mode to increase performance.
20
20
--
21
- local function switch_in_replicaset (mode )
22
- if mode == nil then
23
- mode = false
21
+ local function switch_in_replicaset (replicaset_mode )
22
+ if replicaset_mode == nil then
23
+ replicaset_mode = false
24
24
end
25
25
26
- if not box .space ._queue_inactive_sessions then
26
+ if not box .space ._queue_shared_sessions then
27
27
return
28
28
end
29
29
30
- if box .space ._queue_inactive_sessions .temporary and mode == false then
30
+ if box .space ._queue_shared_sessions .temporary
31
+ and replicaset_mode == false then
31
32
return
32
33
end
33
34
34
- if not box .space ._queue_inactive_sessions .temporary and mode == true then
35
+ if not box .space ._queue_shared_sessions .temporary
36
+ and replicaset_mode == true then
35
37
return
36
38
end
37
39
38
- box .schema .create_space (' _queue_inactive_sessions_mgr ' , {
39
- temporary = not mode ,
40
+ box .schema .create_space (' _queue_shared_sessions_mgr ' , {
41
+ temporary = not replicaset_mode ,
40
42
format = {
41
43
{ name = ' uuid' , type = str_type () },
42
- { name = ' exp_time' , type = num_type () }
44
+ { name = ' exp_time' , type = num_type () },
45
+ { name = ' active' , type = ' boolean' },
43
46
}
44
47
})
45
48
46
- box .space ._queue_inactive_sessions_mgr :create_index (' uuid' , {
49
+ box .space ._queue_shared_sessions_mgr :create_index (' uuid' , {
47
50
type = ' tree' ,
48
51
parts = { 1 , str_type () },
49
52
unique = true
50
53
})
54
+ box .space ._queue_shared_sessions_mgr :create_index (' active' , {
55
+ type = ' tree' ,
56
+ parts = { 3 , ' boolean' , 1 , str_type () },
57
+ unique = true
58
+ })
51
59
52
60
box .begin () -- Disable implicit yields until the transaction ends.
53
- for _ , tuple in box .space ._queue_inactive_sessions :pairs () do
54
- box .space ._queue_inactive_sessions_mgr :insert (tuple )
61
+ for _ , tuple in box .space ._queue_shared_sessions :pairs () do
62
+ box .space ._queue_shared_sessions_mgr :insert (tuple )
55
63
end
56
64
57
- box .space ._queue_inactive_sessions :drop ()
58
- box .space ._queue_inactive_sessions_mgr :rename (' _queue_inactive_sessions ' )
65
+ box .space ._queue_shared_sessions :drop ()
66
+ box .space ._queue_shared_sessions_mgr :rename (' _queue_shared_sessions ' )
59
67
60
68
local status , err = pcall (box .commit )
61
69
if not status then
62
- error ((' Error migrate _queue_inactive_sessions : %s' ):format (tostring (err )))
70
+ error ((' Error migrate _queue_shared_sessions : %s' ):format (tostring (err )))
63
71
end
64
72
end
65
73
@@ -87,37 +95,63 @@ local function identification_init()
87
95
})
88
96
end
89
97
90
- local _mode = queue_session .cfg [' in_replicaset' ] or false
91
- if box .space ._queue_inactive_sessions == nil then
92
- box .schema .create_space (' _queue_inactive_sessions ' , {
93
- temporary = not _mode ,
98
+ local replicaset_mode = queue_session .cfg [' in_replicaset' ] or false
99
+ if box .space ._queue_shared_sessions == nil then
100
+ box .schema .create_space (' _queue_shared_sessions ' , {
101
+ temporary = not replicaset_mode ,
94
102
format = {
95
103
{ name = ' uuid' , type = str_type () },
96
- { name = ' exp_time' , type = num_type () }
104
+ { name = ' exp_time' , type = num_type () },
105
+ { name = ' active' , type = ' boolean' },
97
106
}
98
107
})
99
108
100
- box .space ._queue_inactive_sessions :create_index (' uuid' , {
109
+ box .space ._queue_shared_sessions :create_index (' uuid' , {
101
110
type = ' tree' ,
102
111
parts = { 1 , str_type () },
103
112
unique = true
104
113
})
114
+ box .space ._queue_shared_sessions :create_index (' active' , {
115
+ type = ' tree' ,
116
+ parts = { 3 , ' boolean' , 1 , str_type () },
117
+ unique = true
118
+ })
105
119
else
106
120
switch_in_replicaset (queue_session .cfg [' in_replicaset' ])
121
+
122
+ -- At the start of the queue, we make all active sessions inactive,
123
+ -- and set an expiration time for them. If the ttr setting is not set,
124
+ -- then we delete all sessions.
125
+ local ttr = queue_session .cfg [' ttr' ] or 0
126
+ if ttr > 0 then
127
+ for _ , tuple in box .space ._queue_shared_sessions .index .active :pairs {true } do
128
+ box .space ._queue_shared_sessions :update (tuple [1 ], {
129
+ {' =' , 2 , util .event_time (ttr )},
130
+ {' =' , 3 , false },
131
+ })
132
+ end
133
+ else
134
+ if queue_session ._on_session_remove ~= nil then
135
+ for _ , tuple in box .space ._queue_shared_sessions .index .uuid :pairs () do
136
+ queue_session ._on_session_remove (tuple [1 ])
137
+ end
138
+ end
139
+ box .space ._queue_shared_sessions :truncate ()
140
+ end
107
141
end
108
142
end
109
143
110
144
local function cleanup_inactive_sessions ()
111
145
local cur_time = util .time ()
112
146
113
- for _ , val in box .space ._queue_inactive_sessions :pairs () do
147
+ for _ , val in box .space ._queue_shared_sessions . index . active :pairs { false } do
114
148
local session_uuid = val [1 ]
115
149
local exp_time = val [2 ]
116
150
if cur_time >= exp_time then
117
151
if queue_session ._on_session_remove ~= nil then
118
152
queue_session ._on_session_remove (session_uuid )
119
153
end
120
- box .space ._queue_inactive_sessions :delete {session_uuid }
154
+ box .space ._queue_shared_sessions :delete {session_uuid }
121
155
end
122
156
end
123
157
end
@@ -160,6 +194,7 @@ local function identify(conn_id, session_uuid)
160
194
-- Generate new UUID for the session.
161
195
cur_uuid = uuid .bin ()
162
196
queue_session_ids :insert {conn_id , cur_uuid }
197
+ box .space ._queue_shared_sessions :insert {cur_uuid , 0 , true }
163
198
elseif session_uuid ~= nil then
164
199
-- Validate UUID.
165
200
if not pcall (uuid .frombin , session_uuid ) then
@@ -170,8 +205,8 @@ local function identify(conn_id, session_uuid)
170
205
-- Check that a session with this uuid exists.
171
206
local ids_by_uuid = queue_session_ids .index .uuid :select (
172
207
session_uuid , { limit = 1 })[1 ]
173
- local inactive_session = box .space ._queue_inactive_sessions :get (session_uuid )
174
- if ids_by_uuid == nil and inactive_session == nil then
208
+ local shared_session = box .space ._queue_shared_sessions :get (session_uuid )
209
+ if ids_by_uuid == nil and shared_session == nil then
175
210
error (' The UUID ' .. uuid .frombin (session_uuid ):str () ..
176
211
' is unknown.' )
177
212
end
@@ -183,10 +218,15 @@ local function identify(conn_id, session_uuid)
183
218
queue_session_ids :insert ({conn_id , session_uuid })
184
219
cur_uuid = session_uuid
185
220
end
186
- end
187
221
188
- -- Exclude the session from inactive.
189
- box .space ._queue_inactive_sessions :delete {cur_uuid }
222
+ -- Make session active.
223
+ if shared_session then
224
+ box .space ._queue_shared_sessions :update (shared_session [1 ], {
225
+ {' =' , 2 , 0 },
226
+ {' =' , 3 , true },
227
+ })
228
+ end
229
+ end
190
230
191
231
return cur_uuid
192
232
end
@@ -209,21 +249,33 @@ local function disconnect(conn_id)
209
249
{ limit = 1 })[1 ]
210
250
211
251
-- If a queue session doesn't have any active connections it should be
212
- -- removed (if ttr is absent) or moved to the "inactive sessions" list.
252
+ -- removed (if ttr is absent) or change the `active` flag to make the
253
+ -- session inactive.
213
254
if session_ids == nil then
214
255
local ttr = queue_session .cfg [' ttr' ] or 0
215
256
if ttr > 0 then
216
- box .space ._queue_inactive_sessions :insert {session_uuid , util .event_time (ttr )}
257
+ local tuple = box .space ._queue_shared_sessions :get {session_uuid }
258
+ if tuple == nil then
259
+ box .space ._queue_shared_sessions :insert {
260
+ session_uuid , util .event_time (ttr ), false
261
+ }
262
+ else
263
+ box .space ._queue_shared_sessions :update (tuple [1 ], {
264
+ {' =' , 2 , util .event_time (ttr )},
265
+ {' =' , 3 , false },
266
+ })
267
+ end
217
268
elseif queue_session ._on_session_remove ~= nil then
218
269
queue_session ._on_session_remove (session_uuid )
270
+ box .space ._queue_shared_sessions .index .uuid :delete {session_uuid }
219
271
end
220
272
end
221
273
end
222
274
223
275
local function grant (user )
224
276
box .schema .user .grant (user , ' read, write' , ' space' , ' _queue_session_ids' ,
225
277
{ if_not_exists = true })
226
- box .schema .user .grant (user , ' read, write' , ' space' , ' _queue_inactive_sessions ' ,
278
+ box .schema .user .grant (user , ' read, write' , ' space' , ' _queue_shared_sessions ' ,
227
279
{ if_not_exists = true })
228
280
end
229
281
@@ -246,7 +298,7 @@ local function validate_opts(opts)
246
298
error (' Invalid value of ttr: ' .. tostring (val ))
247
299
end
248
300
elseif key == ' in_replicaset' then
249
- -- do nothing
301
+ -- Do nothing.
250
302
else
251
303
error (' Unknown option ' .. tostring (key ))
252
304
end
@@ -269,8 +321,8 @@ local function cfg(self, opts)
269
321
switch_in_replicaset (self [' in_replicaset' ])
270
322
end
271
323
272
- local function exist_inactive (session_uuid )
273
- if box .space ._queue_inactive_sessions :get {session_uuid } then
324
+ local function exist_shared (session_uuid )
325
+ if box .space ._queue_shared_sessions :get {session_uuid } then
274
326
return true
275
327
end
276
328
@@ -287,7 +339,7 @@ local method = {
287
339
on_session_remove = on_session_remove ,
288
340
start = start ,
289
341
stop = stop ,
290
- exist_inactive = exist_inactive
342
+ exist_shared = exist_shared
291
343
}
292
344
293
345
return setmetatable (queue_session , { __index = method })
0 commit comments