Comparison

core/storagemanager.lua @ 8654:425de10efde4

storagemanager: Log warning on storage access outside of async contexts
author Matthew Wild <mwild1@gmail.com>
date Thu, 22 Mar 2018 16:25:20 +0000
parent 8555:4f0f5b49bb03
child 8670:800c648827e3
comparison
equal deleted inserted replaced
8653:dab9b8af0f01 8654:425de10efde4
1 1
2 local type, pairs = type, pairs; 2 local type, pairs = type, pairs;
3 local setmetatable = setmetatable; 3 local setmetatable = setmetatable;
4 local rawset, error = rawset, error;
4 5
5 local config = require "core.configmanager"; 6 local config = require "core.configmanager";
6 local datamanager = require "util.datamanager"; 7 local datamanager = require "util.datamanager";
7 local modulemanager = require "core.modulemanager"; 8 local modulemanager = require "core.modulemanager";
8 local multitable = require "util.multitable"; 9 local multitable = require "util.multitable";
9 local hosts = hosts; 10 local hosts = hosts;
10 local log = require "util.logger".init("storagemanager"); 11 local log = require "util.logger".init("storagemanager");
12 local async = require "util.async";
13 local debug = debug;
11 14
12 local prosody = prosody; 15 local prosody = prosody;
13 16
14 local _ENV = nil; 17 local _ENV = nil;
15 -- luacheck: std none 18 -- luacheck: std none
27 return null_storage_method; 30 return null_storage_method;
28 end 31 end
29 } 32 }
30 ); 33 );
31 34
35 local async_check = config.get("*", "storage_async_check") ~= false;
36
32 local stores_available = multitable.new(); 37 local stores_available = multitable.new();
38
39 local function check_async_wrapper(event)
40 local store = event.store;
41 event.store = setmetatable({}, {
42 __index = function (t, method_name)
43 local original_method = store[method_name];
44 if type(original_method) ~= "function" then
45 if original_method then
46 rawset(t, method_name, original_method);
47 end
48 return original_method;
49 end
50 local wrapped_method = function (...)
51 if not async.ready() then
52 log("warn", "ASYNC-01: Attempt to access storage outside async context, "
53 .."see https://prosody.im/doc/developers/async - %s", debug.traceback());
54 end
55 return original_method(...);
56 end
57 rawset(t, method_name, wrapped_method);
58 return wrapped_method;
59 end;
60 });
61 end
33 62
34 local function initialize_host(host) 63 local function initialize_host(host)
35 local host_session = hosts[host]; 64 local host_session = hosts[host];
36 host_session.events.add_handler("item-added/storage-provider", function (event) 65 host_session.events.add_handler("item-added/storage-provider", function (event)
37 local item = event.item; 66 local item = event.item;
40 69
41 host_session.events.add_handler("item-removed/storage-provider", function (event) 70 host_session.events.add_handler("item-removed/storage-provider", function (event)
42 local item = event.item; 71 local item = event.item;
43 stores_available:set(host, item.name, nil); 72 stores_available:set(host, item.name, nil);
44 end); 73 end);
74 if async_check then
75 host_session.events.add_handler("store-opened", check_async_wrapper);
76 end
45 end 77 end
46 prosody.events.add_handler("host-activated", initialize_host, 101); 78 prosody.events.add_handler("host-activated", initialize_host, 101);
47 79
48 local function load_driver(host, driver_name) 80 local function load_driver(host, driver_name)
49 if driver_name == "null" then 81 if driver_name == "null" then