File cache sync via curl (#2851)

* Add sendevent when using file caching

* Create clear_cache.lua

FS receives a command via curl to call this script which deletes the single cache entry or flushes the entire cache.

* Create file_cache.lua

This scripts monitors for custom events. When an event is processed it will send out a command via curl to other FS servers telling them to clear their cache. 

This must be called from conf/autoload_configs/lua.conf.xml
 <param name="startup-script" value="app/server/resources/memcache.lua"/>
This commit is contained in:
konradSC
2017-09-20 18:19:56 -04:00
committed by FusionPBX
parent 940cb27681
commit 73bea2f815
3 changed files with 157 additions and 7 deletions

View File

@@ -104,17 +104,34 @@ class cache {
//close event socket
fclose($fp);
}
//cache method file
if ($_SESSION['cache']['method']['text'] == "file") {
$key = str_replace(":", ".", $key);
if (file_exists($_SESSION['cache']['location']['text'] . "/" . $key)) {
unlink($_SESSION['cache']['location']['text'] . "/" . $key);
}
if (file_exists($_SESSION['cache']['location']['text'] . "/" . $key . ".tmp")) {
unlink($_SESSION['cache']['location']['text'] . "/" . $key . ".tmp");
}
// connect to event socket
$fp = event_socket_create($_SESSION['event_socket_ip_address'], $_SESSION['event_socket_port'], $_SESSION['event_socket_password']);
if ($fp === false) {
return false;
}
//send a custom event
$event = "sendevent CUSTOM\n";
$event .= "Event-Name: CUSTOM\n";
$event .= "Event-Subclass: fusion::file\n";
$event .= "API-Command: cache\n";
$event .= "API-Command-Argument: delete ".$key."\n";
event_socket_request($fp, $event);
//remove the local files
if (file_exists($_SESSION['cache']['location']['text'] . "/" . $key)) {
unlink($_SESSION['cache']['location']['text'] . "/" . $key);
}
if (file_exists($_SESSION['cache']['location']['text'] . "/" . $key . ".tmp")) {
unlink($_SESSION['cache']['location']['text'] . "/" . $key . ".tmp");
}
}
// return result
@@ -147,16 +164,22 @@ class cache {
//close event socket
fclose($fp);
}
//cache method file
if ($_SESSION['cache']['method']['text'] == "file") {
// connect to event socket
$fp = event_socket_create($_SESSION['event_socket_ip_address'], $_SESSION['event_socket_port'], $_SESSION['event_socket_password']);
if ($fp === false) {
return false;
}
//send a custom event
$event = "sendevent CUSTOM\n";
$event .= "Event-Name: CUSTOM\n";
$event .= "Event-Subclass: fusion::file\n";
$event .= "API-Command: file\n";
$event .= "API-Command: cache\n";
$event .= "API-Command-Argument: flush\n";
event_socket_request($fp, $event);

View File

@@ -0,0 +1,37 @@
--includes
require "resources.functions.config";
local Database = require "resources.functions.database";
local Settings = require "resources.functions.lazy_settings"
dbh = Database.new('system');
local settings = Settings.new(dbh, domain_name, domain_uuid);
--define trim
function trim (s)
return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
end
--get the argv values
cmd = argv[1];
file = argv[2];
--get the cache directory
local cache_dir = settings:get('cache', 'location', 'text')
if (cmd ~= nil) then
cmd = trim(cmd);
freeswitch.consoleLog("NOTICE","api_command: "..cmd .. " cache\n");
end
if (cmd == "flush") then
os.execute("rm " .. cache_dir .. "/*");
end
if (cmd == "delete") then
if (file ~= nil) then
file = trim(file);
freeswitch.consoleLog("NOTICE","api_command: delete ".. cache_dir .. "/" .. file .. "\n");
os.remove(cache_dir.."/"..file);
end
end

View File

@@ -0,0 +1,90 @@
--description
--monitor custom memcache event and clear memcache on remote servers
--protect xmlrpc using a firewall on the server to limit access by ip address
--dependencies
--install mod_curl freeswitch module
--uncomment mod_curl from modules.conf when compiling freeswitch
--xmlrpc
--open port xmlrpc port for other master server IP addresses
--change the password for xmlrpc in system -> settings
--conf/autoload_configs/lua.conf.xml
-- <param name="startup-script" value="app/server/resources/memcache.lua"/>
--iptables
-- /sbin/iptables -I INPUT -j ACCEPT -p tcp --dport 8080 -s x.x.x.x/32
-- ubuntu: service iptables-persistent save
--define the servers running freeswitch do not include local
--[[
#put this in local.lua
servers = {}
x = 0;
servers[x] = {}
servers[x]['method'] = "curl";
servers[x]['username'] = "freeswitch";
servers[x]['password'] = "freeswitch";
servers[x]['hostname'] = "x.x.x.x";
servers[x]['port'] = "8080";
x = x + 1;
servers[x] = {}
servers[x]['method'] = "curl";
servers[x]['username'] = "freeswitch";
servers[x]['password'] = "freeswitch";
servers[x]['hostname'] = "x.x.x.x";
servers[x]['port'] = "8080";
]]
--includes config.lua which will include local.lua if it exists
require "resources.functions.config"
--subscribe to the events
--events = freeswitch.EventConsumer("all");
events = freeswitch.EventConsumer("CUSTOM");
--define trim
function trim (s)
return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
end
--prepare the api object
api = freeswitch.API();
--get the events
for event in (function() return events:pop(1) end) do
--serialize the data for the console
--freeswitch.consoleLog("notice","event:" .. event:serialize("xml") .. "\n");
--freeswitch.consoleLog("notice","event:" .. event:serialize("json") .. "\n");
--get the uuid
local api_command = event:getHeader("API-Command");
if (api_command ~= nil) then
api_command = trim(api_command);
freeswitch.consoleLog("NOTICE","api_command: "..api_command .. "\n");
end
if (api_command == "cache") then
cache_updated = false;
local api_command_argument = event:getHeader("API-Command-Argument");
if (api_command_argument ~= nil) then
api_command_argument = trim(api_command_argument);
end
if (api_command_argument ~= nil) then
if (api_command_argument == "flush") then
cache_updated = true
end
if (string.sub(api_command_argument, 0, 6) == "delete") then
cache_updated = true
end
if (cache_updated) then
for key,row in pairs(servers) do
if (row.method == "ssh") then
api_command_argument = api_command_argument:gsub("%%20", " ");
cmd = [[ ssh ]]..row.username..[[@]]..row.hostname..[[ " ]]..api_command_argument..[["]];
freeswitch.consoleLog("INFO", "[notice] command: ".. cmd .. "\n");
os.execute(cmd);
end
end
end
end
end
end