diff --git a/modules/predict/predict.lua b/modules/predict/predict.lua index d462e0ac28b76fb5675e106280fdf56da9cce491..7b25497230d6c89035efcf5e5f7e260b618afee3 100644 --- a/modules/predict/predict.lua +++ b/modules/predict/predict.lua @@ -113,6 +113,7 @@ local function generate(epoch_now) end function predict.process(ev) + if not stats then error("'stats' module required") end -- Start a new epoch, or continue sampling predict.ev_sample = nil local epoch_now = current_epoch() @@ -158,9 +159,6 @@ function predict.deinit(module) end function predict.config(config) - if not stats then - error("'stats' module required") - end -- Reconfigure if type(config) ~= 'table' then return end if config.window then predict.window = config.window end diff --git a/modules/tinyweb/tinyweb.go b/modules/tinyweb/tinyweb.go index aaf51fdbbc3448a51cb067f8d04512037c04dca4..16aa1bd25a6355196db011fecbdae80d2ff81f91 100644 --- a/modules/tinyweb/tinyweb.go +++ b/modules/tinyweb/tinyweb.go @@ -14,7 +14,6 @@ static inline const knot_layer_api_t *_layer(void) import "C" import ( "os" - "sync" "unsafe" "fmt" "net" @@ -25,12 +24,6 @@ import ( "github.com/abh/geoip" ) -type Sample struct { - qname string - qtype int - addr net.IP - secure bool -} type QueryInfo struct { Qname string Qtype string @@ -41,10 +34,6 @@ type QueryInfo struct { // Global context var resolver *C.struct_kr_context -// Synchronisation -var wg sync.WaitGroup -// Global channel for metrics -var ch_metrics chan Sample // FIFO of last-seen metrics var fifo_metrics [10] QueryInfo var fifo_metrics_i = 0 @@ -126,35 +115,30 @@ func serve_stats(w http.ResponseWriter, r *http.Request) { * Module implementation. */ +func process_sample(qname string, qtype int, addr net.IP, secure bool) { + var qtype_str [16] byte + C.knot_rrtype_to_string(C.uint16_t(qtype), (*C.char)(unsafe.Pointer(&qtype_str[0])), C.size_t(16)) + // Sample NS country code + var cc string + switch len(addr) { + case 4: if (geo_db != nil) { cc, _ = geo_db.GetCountry(addr.String()) } + case 16: if (geo_db6 != nil) { cc, _ = geo_db6.GetCountry_v6(addr.String()) } + default: return + } + // Count occurences + if freq, exists := geo_freq[cc]; exists { + geo_freq[cc] = freq + 1 + } else { + geo_freq[cc] = 1 + } + fifo_metrics[fifo_metrics_i] = QueryInfo{qname, string(qtype_str[:]), addr.String(), secure, cc} + fifo_metrics_i = (fifo_metrics_i + 1) % len(fifo_metrics) +} + //export tinyweb_init func tinyweb_init(module *C.struct_kr_module) int { resolver = (*C.struct_kr_context)(module.data) - ch_metrics = make(chan Sample, 10) geo_freq = make(map[string]int) - // Start sample collector goroutine - wg.Add(1) - go func() { - defer wg.Done() - for msg := range ch_metrics { - var qtype_str [16] byte - C.knot_rrtype_to_string(C.uint16_t(msg.qtype), (*C.char)(unsafe.Pointer(&qtype_str[0])), C.size_t(16)) - // Sample NS country code - var cc string - switch len(msg.addr) { - case 4: if (geo_db != nil) { cc, _ = geo_db.GetCountry(msg.addr.String()) } - case 16: if (geo_db6 != nil) { cc, _ = geo_db6.GetCountry_v6(msg.addr.String()) } - default: continue - } - // Count occurences - if freq, exists := geo_freq[cc]; exists { - geo_freq[cc] = freq + 1 - } else { - geo_freq[cc] = 1 - } - fifo_metrics[fifo_metrics_i] = QueryInfo{msg.qname, string(qtype_str[:]), msg.addr.String(), msg.secure, cc} - fifo_metrics_i = (fifo_metrics_i + 1) % len(fifo_metrics) - } - }() return 0 } @@ -196,7 +180,6 @@ func tinyweb_config(module *C.struct_kr_module, conf *C.char) int { http.HandleFunc("/d3.js", serve_file) http.HandleFunc("/", serve_page) // @todo Not sure how to cancel this routine yet - // wg.Add(1) fmt.Printf("[tinyweb] listening on %s\n", addr) go http.ListenAndServe(addr, nil) return 0 @@ -204,8 +187,6 @@ func tinyweb_config(module *C.struct_kr_module, conf *C.char) int { //export tinyweb_deinit func tinyweb_deinit(module *C.struct_kr_module) int { - close(ch_metrics) - wg.Wait() return 0 } @@ -232,8 +213,8 @@ func consume(ctx *C.knot_layer_t, pkt *C.knot_pkt_t) C.int { defer C.free(unsafe.Pointer(qname)) qtype := C.knot_pkt_qtype(pkt) secure := (bool)(C.knot_pkt_has_dnssec(pkt)) - // Process metric - ch_metrics <- Sample{C.GoString(qname), (int)(qtype), ip, secure} + // Sample metric + process_sample(C.GoString(qname), int(qtype), ip, secure) return state }