From commits-return-322-apmail-whimsical-commits-archive=whimsical.apache.org@whimsical.apache.org Tue Jan 19 14:40:28 2016 Return-Path: X-Original-To: apmail-whimsical-commits-archive@minotaur.apache.org Delivered-To: apmail-whimsical-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id EBEC11839B for ; Tue, 19 Jan 2016 14:40:27 +0000 (UTC) Received: (qmail 58559 invoked by uid 500); 19 Jan 2016 14:40:27 -0000 Delivered-To: apmail-whimsical-commits-archive@whimsical.apache.org Received: (qmail 58539 invoked by uid 500); 19 Jan 2016 14:40:27 -0000 Mailing-List: contact commits-help@whimsical.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@whimsical.apache.org Delivered-To: mailing list commits@whimsical.apache.org Received: (qmail 58530 invoked by uid 99); 19 Jan 2016 14:40:27 -0000 Received: from Unknown (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 19 Jan 2016 14:40:27 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id 6BB991A061C for ; Tue, 19 Jan 2016 14:40:27 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 1.247 X-Spam-Level: * X-Spam-Status: No, score=1.247 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RP_MATCHES_RCVD=-0.554, URIBL_BLOCKED=0.001] autolearn=disabled Received: from mx1-us-west.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id TipESP7XEo3P for ; Tue, 19 Jan 2016 14:40:14 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx1-us-west.apache.org (ASF Mail Server at mx1-us-west.apache.org) with ESMTP id 29CDA215D0 for ; Tue, 19 Jan 2016 14:40:14 +0000 (UTC) Received: from matt.apache.org (unknown [207.244.88.130]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id 975F8E0185 for ; Tue, 19 Jan 2016 14:40:13 +0000 (UTC) Received: by matt.apache.org (ASF Mail Server at matt.apache.org, from userid 33) id BD206C736; Tue, 19 Jan 2016 14:40:12 +0000 (UTC) From: Sam Ruby Reply-To: commits@whimsical.apache.org To: commits@whimsical.apache.org Subject: [whimsy.git] [1/1] Commit ff42edd: invoke each monitor in a separate thread Message-Id: <20160119144012.BD206C736@matt.apache.org> Date: Tue, 19 Jan 2016 14:40:12 +0000 (UTC) Commit ff42edd688014d06726b6edd7e29e34a1e68a800: invoke each monitor in a separate thread Branch: refs/heads/master Author: Sam Ruby Committer: Sam Ruby Pusher: rubys ------------------------------------------------------------ www/status/README.md | +++++ ------ www/status/monitor.rb | +++++ ---- ------------------------------------------------------------ 78 changes: 44 additions, 34 deletions. ------------------------------------------------------------ diff --git a/www/status/README.md b/www/status/README.md index c37e42d..ed4130e 100644 --- a/www/status/README.md +++ b/www/status/README.md @@ -91,12 +91,11 @@ no more often than once a minute, and are passed the normalized results of the previous call. As monitors are called in response to a ping, they are expected to produce -results in sub-second time in order to avoid the ping timing out. (Currently -monitors are called in series, but in the future this may change to threads so -that statuses may be collected in parallel.) Monitors that perform activities -that take a substantial amount of time may elect to do so less frequently than -once a minute, and can take advantage of the `mtime` values to determine when -to do so. +results in sub-second time in order to avoid the ping timing out. (Monitors +are run in separate threads to minimize the total elapsed time). Monitors +that perform activities that take a substantial amount of time may elect to do +so less frequently than once a minute, and can take advantage of the `mtime` +values to determine when to do so. Results are collected into a hash, and that hash is then normalized. Normalization resolves default values for items like levels and titles diff --git a/www/status/monitor.rb b/www/status/monitor.rb index 781d997..6822875 100644 --- a/www/status/monitor.rb +++ b/www/status/monitor.rb @@ -6,6 +6,7 @@ require 'json' require 'time' +require 'thread' class Monitor # match http://getbootstrap.com/components/#alerts @@ -30,42 +31,52 @@ def initialize(args = []) return end - # invoke each monitor, collecting status from each - newstatus = {} + # start each monitor in a separate thread + threads = [] self.class.singleton_methods.sort.each do |method| next if args.length > 0 and not args.include? method.to_s - # invoke method to determine current status - begin - previous = baseline[method] || {mtime: Time.at(0)} - status = Monitor.send(method, previous) || previous - - # convert non-hashes in proper statuses - if not status.instance_of? Hash - if status.instance_of? String or status.instance_of? Array - status = {data: status} - else - status = {level: 'danger', data: status.inspect} + threads << Thread.new do + begin + # invoke method to determine current status + previous = baseline[method] || {mtime: Time.at(0)} + status = Monitor.send(method, previous) || previous + + # convert non-hashes in proper statuses + if not status.instance_of? Hash + if status.instance_of? String or status.instance_of? Array + status = {data: status} + else + status = {level: 'danger', data: status.inspect} + end end - end - rescue Exception => e - status = { - level: 'danger', - data: { - exception: { - level: 'danger', - text: e.inspect, - data: e.backtrace + rescue Exception => e + status = { + level: 'danger', + data: { + exception: { + level: 'danger', + text: e.inspect, + data: e.backtrace + } } } - } - end + end - # default mtime to now - status['mtime'] ||= Time.now if status.instance_of? Hash + # default mtime to now + status['mtime'] ||= Time.now if status.instance_of? Hash - # update baseline - newstatus[method] = status + # store status in thread local storage + Thread.current[:name] = method.to_s + Thread.current[:status] = status + end + end + + # collect status from each monitor thread + newstatus = {} + threads.each do |thread| + thread.join + newstatus[thread[:name]] = thread[:status] end # normalize status