Diff

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
line wrap: on
line diff
--- a/core/storagemanager.lua	Thu Mar 22 16:24:22 2018 +0000
+++ b/core/storagemanager.lua	Thu Mar 22 16:25:20 2018 +0000
@@ -1,6 +1,7 @@
 
 local type, pairs = type, pairs;
 local setmetatable = setmetatable;
+local rawset, error = rawset, error;
 
 local config = require "core.configmanager";
 local datamanager = require "util.datamanager";
@@ -8,6 +9,8 @@
 local multitable = require "util.multitable";
 local hosts = hosts;
 local log = require "util.logger".init("storagemanager");
+local async = require "util.async";
+local debug = debug;
 
 local prosody = prosody;
 
@@ -29,8 +32,34 @@
 	}
 );
 
+local async_check = config.get("*", "storage_async_check") ~= false;
+
 local stores_available = multitable.new();
 
+local function check_async_wrapper(event)
+	local store = event.store;
+	event.store = setmetatable({}, {
+		__index = function (t, method_name)
+			local original_method = store[method_name];
+			if type(original_method) ~= "function" then
+				if original_method then
+					rawset(t, method_name, original_method);
+				end
+				return original_method;
+			end
+			local wrapped_method = function (...)
+				if not async.ready() then
+					log("warn", "ASYNC-01: Attempt to access storage outside async context, "
+					  .."see https://prosody.im/doc/developers/async - %s", debug.traceback());
+				end
+				return original_method(...);
+			end
+			rawset(t, method_name, wrapped_method);
+			return wrapped_method;
+		end;
+	});
+end
+
 local function initialize_host(host)
 	local host_session = hosts[host];
 	host_session.events.add_handler("item-added/storage-provider", function (event)
@@ -42,6 +71,9 @@
 		local item = event.item;
 		stores_available:set(host, item.name, nil);
 	end);
+	if async_check then
+		host_session.events.add_handler("store-opened", check_async_wrapper);
+	end
 end
 prosody.events.add_handler("host-activated", initialize_host, 101);