Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions .github/workflows/flowview-query-go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# +-------------------------------------------------------------------------+
# | Copyright (C) 2004-2026 The Cacti Group |
# | |
# | This program is free software; you can redistribute it and/or |
# | modify it under the terms of the GNU General Public License |
# | as published by the Free Software Foundation; either version 2 |
# | of the License, or (at your option) any later version. |
# +-------------------------------------------------------------------------+

name: FlowView Query Service (Go)

on:
push:
branches:
- main
- develop
paths:
- 'service/flowview-query/**'
- '.github/workflows/flowview-query-go.yml'
pull_request:
branches:
- main
- develop
paths:
- 'service/flowview-query/**'
- '.github/workflows/flowview-query-go.yml'

permissions:
contents: read

jobs:
go-test:
runs-on: ubuntu-latest

name: Build, vet and test the Go query service

defaults:
run:
working-directory: service/flowview-query

steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Set up Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: service/flowview-query/go.mod
cache-dependency-path: service/flowview-query/go.sum

- name: Verify formatting
run: |
unformatted="$(gofmt -l .)"
if [ -n "$unformatted" ]; then
echo "The following files are not gofmt-clean:"
echo "$unformatted"
exit 1
fi

- name: Vet
run: go vet ./...

- name: Build
run: go build ./...

- name: Test
run: go test -race -cover ./...
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

--- develop ---

* feature: Add an optional FlowView Query Service (a long-running Go service under service/flowview-query) as a selectable Parallel Query Backend under FlowView Settings (default Legacy PHP Runner); when enabled, the parallel query parent runner (flowview_runner.php) delegates the whole query to the service over localhost instead of forking a PHP worker per shard, running the same cache-aware map-reduce (sharing parallel_database_query_shard_cache) and writing results back, with automatic fallback to the legacy runner when the service is unreachable

* bug: Load the pre-1.3 report compatibility shims (reports_run/reports_queue/reports_log_and_notify) only when the running Cacti is older than 1.3, decided with cacti_version_compare(CACTI_VERSION, '1.3', ...) rather than a function_exists() probe; because the plugin's functions.php is included during plugin init before core loads lib/reports.php, the function_exists() check ran while the now-native helpers were still absent, declared the shims, and core then fatally redeclared reports_log_and_notify() on 1.3.0 develop builds (falls back to function_exists() only when the Cacti version helpers are unavailable, e.g. the unit tests)
* security: Move the plugin's remaining inline event handlers to CSP-safe bindings so the pages no longer trip Cacti's Content-Security-Policy script-src-attr directive: confirmation Cancel buttons use the `cactiReturnTo` class, the database/filter selects are bound via change() in their ready blocks, and the main filter's sort/report selects and time-shift icons are bound in flowview_display_filter's ready block
* dev: Replace the translation-template CI check that regenerated locales/po/cacti.pot and compared it with a diff-based gate (tests/bin/check-i18n-pot.php) requiring cacti.pot to be updated only when a pull request adds, removes, or modifies an i18n function call
Expand Down
21 changes: 20 additions & 1 deletion flowview_runner.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,26 @@

$current_time = time();

$stats = parallel_database_parent_runner($query_id);
/* The Query Service backend runs the whole map-reduce in-process (shards as
* goroutines, shared shard cache) and writes results back, so we do not fork
* per-shard PHP workers. Fall back to the legacy parent runner when the
* service is disabled or unreachable. */
$backend = read_config_option('flowview_parallel_backend');

if ($backend == 'service' && flowview_query_service_run(array($query_id))) {
$stats = array('threads' => 0, 'shards' => 0, 'cached' => 0, 'total_size' => 0, 'cached_size' => 0);
} else {
if ($backend == 'service') {
cacti_log('WARNING: FlowView Query Service unavailable, falling back to the Legacy PHP Runner', false, 'FLOWVIEW');

/* a partial service run may have staged map rows and left shards
* mid-flight; reset to a clean pending state so the legacy runner
* relaunches every shard and does not hang or duplicate data */
flowview_parallel_reset_query($query_id);
}

$stats = parallel_database_parent_runner($query_id);
}

unregister_process('flowview', "db_query_{$query_id}", 0);

Expand Down
42 changes: 41 additions & 1 deletion locales/po/cacti.pot
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Cacti \n"
"Report-Msgid-Bugs-To: developers@cacti.net\n"
"POT-Creation-Date: 2026-09-30 10:11-0400\n"
"POT-Creation-Date: 2026-10-10 20:49-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Cacti Developers <developers@cacti.net>>\n"
"Language-Team: Cacti Developers <developers@cacti.net>\n"
Expand Down Expand Up @@ -2675,6 +2675,46 @@ msgstr ""
msgid "Parallel Queries"
msgstr ""

#: setup.php
msgid "Parallel Query Backend"
msgstr ""

#: setup.php
msgid "Choose how parallel FlowView queries are executed. The Legacy PHP Runner forks the flowview_runner.php process per query and shard. The FlowView Query Service dispatches the same map-reduce work to a long-running Go service over localhost, avoiding per-query process startup and database polling latency. Requires the flowview-query service (see plugins/flowview/service/flowview-query) to be installed and running."
msgstr ""

#: setup.php
msgid "Legacy PHP Runner"
msgstr ""

#: setup.php
msgid "FlowView Query Service"
msgstr ""

#: setup.php
msgid "Query Service URL"
msgstr ""

#: setup.php
msgid "Base URL of the FlowView Query Service, for example http://127.0.0.1:8699. Leave blank to auto-discover the ephemeral port from the service's port file."
msgstr ""

#: setup.php
msgid "Query Service Port File"
msgstr ""

#: setup.php
msgid "Path to the port file the FlowView Query Service writes its bound address to. Used to discover the service endpoint when the Query Service URL above is blank."
msgstr ""

#: setup.php
msgid "Query Service Token"
msgstr ""

#: setup.php
msgid "Optional shared secret. When set, Cacti sends it to the FlowView Query Service as an \"Authorization: Bearer\" header and the service rejects any state-changing request that does not present the same token. Set the matching value in the service's config file (auth_token) or the FLOWVIEW_QUERY_TOKEN environment variable. Recommended whenever the service is reachable by anything other than trusted local processes."
msgstr ""

#: setup.php
msgid "Max Concurrent Threads"
msgstr ""
Expand Down
4 changes: 4 additions & 0 deletions service/flowview-query/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/flowview-query
*.exe
*.test
*.out
Loading
Loading