Comparison

plugins/muc/mod_muc.lua @ 8657:a804f2e75f10

MUC: Prevent room eviction on storage failure
author Kim Alvefur <zash@zash.se>
date Wed, 07 Mar 2018 17:38:01 +0100
parent 8656:0e84814a7ece
child 8658:75c7e887c4b9
comparison
equal deleted inserted replaced
8656:0e84814a7ece 8657:a804f2e75f10
127 local eviction_hit_rate = module:measure("room_eviction", "rate"); 127 local eviction_hit_rate = module:measure("room_eviction", "rate");
128 local rooms = cache.new(module:get_option_number("muc_room_cache_size", 100), function (jid, room) 128 local rooms = cache.new(module:get_option_number("muc_room_cache_size", 100), function (jid, room)
129 module:log("debug", "Evicting room %s", jid); 129 module:log("debug", "Evicting room %s", jid);
130 eviction_hit_rate(); 130 eviction_hit_rate();
131 room_items_cache[room.jid] = room:get_public() and room:get_name() or nil; 131 room_items_cache[room.jid] = room:get_public() and room:get_name() or nil;
132 room_save(room, nil, true); -- Force to disk 132 local ok, err = room_save(room, nil, true); -- Force to disk
133 if not ok then
134 module:log("error", "Failed to swap inactive room %s to disk: %s", jid, err);
135 return false;
136 end
133 end); 137 end);
134 138
135 -- Automatically destroy empty non-persistent rooms 139 -- Automatically destroy empty non-persistent rooms
136 module:hook("muc-occupant-left",function(event) 140 module:hook("muc-occupant-left",function(event)
137 local room = event.room 141 local room = event.room
139 module:fire_event("muc-room-destroyed", { room = room }); 143 module:fire_event("muc-room-destroyed", { room = room });
140 end 144 end
141 end, -1); 145 end, -1);
142 146
143 function track_room(room) 147 function track_room(room)
144 rooms:set(room.jid, room); 148 if rooms:set(room.jid, room) then
145 -- When room is created, over-ride 'save' method 149 -- When room is created, over-ride 'save' method
146 room.save = room_save; 150 room.save = room_save;
151 return room;
152 end
153 return false;
147 end 154 end
148 155
149 local function restore_room(jid) 156 local function restore_room(jid)
150 local node = jid_split(jid); 157 local node = jid_split(jid);
151 local data, err = room_configs:get(node); 158 local data, err = room_configs:get(node);
152 local state = room_state:get(node); 159 local state = room_state:get(node);
153 if data then 160 if data then
154 module:log("debug", "Restoring room %s from storage", jid); 161 module:log("debug", "Restoring room %s from storage", jid);
155 local room = muclib.restore_room(data, state); 162 local room = muclib.restore_room(data, state);
156 track_room(room); 163 return track_room(room);
157 return room;
158 elseif err then 164 elseif err then
159 module:log("error", "Error restoring room %s from storage: %s", jid, err); 165 module:log("error", "Error restoring room %s from storage: %s", jid, err);
160 local room = muclib.new_room(jid, { locked = math.huge }); 166 local room = muclib.new_room(jid, { locked = math.huge });
161 return room; 167 return room;
162 end 168 end
214 seen[room.jid] = true; 220 seen[room.jid] = true;
215 end 221 end
216 for room_jid in pairs(persistent_rooms_storage:get(nil) or {}) do 222 for room_jid in pairs(persistent_rooms_storage:get(nil) or {}) do
217 if not seen[room_jid] then 223 if not seen[room_jid] then
218 local room = restore_room(room_jid); 224 local room = restore_room(room_jid);
219 if room == nil then 225 if room then
226 coroutine.yield(room);
227 else
220 module:log("error", "Missing data for room '%s', omitting from iteration", room_jid); 228 module:log("error", "Missing data for room '%s', omitting from iteration", room_jid);
221 else
222 coroutine.yield(room);
223 end 229 end
224 end 230 end
225 end 231 end
226 end); 232 end);
227 end 233 end