From b969629f58f33ab8ae766e0811ff7e51bcc41d58 Mon Sep 17 00:00:00 2001 From: konradSC Date: Wed, 20 Sep 2017 18:19:56 -0400 Subject: [PATCH] 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 --- resources/classes/cache.php | 37 ++++++-- .../app/servers/resources/clear_cache.lua | 37 ++++++++ .../app/servers/resources/file_cache.lua | 90 +++++++++++++++++++ 3 files changed, 157 insertions(+), 7 deletions(-) create mode 100644 resources/install/scripts/app/servers/resources/clear_cache.lua create mode 100644 resources/install/scripts/app/servers/resources/file_cache.lua diff --git a/resources/classes/cache.php b/resources/classes/cache.php index c9b1111f2f..249bbb93df 100644 --- a/resources/classes/cache.php +++ b/resources/classes/cache.php @@ -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); diff --git a/resources/install/scripts/app/servers/resources/clear_cache.lua b/resources/install/scripts/app/servers/resources/clear_cache.lua new file mode 100644 index 0000000000..baca32b602 --- /dev/null +++ b/resources/install/scripts/app/servers/resources/clear_cache.lua @@ -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 diff --git a/resources/install/scripts/app/servers/resources/file_cache.lua b/resources/install/scripts/app/servers/resources/file_cache.lua new file mode 100644 index 0000000000..960a66611d --- /dev/null +++ b/resources/install/scripts/app/servers/resources/file_cache.lua @@ -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 + -- + --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