clawsql 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +97 -0
- package/README.md +372 -0
- package/dist/__tests__/config/settings.test.d.ts +5 -0
- package/dist/__tests__/config/settings.test.d.ts.map +1 -0
- package/dist/__tests__/config/settings.test.js +154 -0
- package/dist/__tests__/config/settings.test.js.map +1 -0
- package/dist/__tests__/core/discovery/topology.test.d.ts +5 -0
- package/dist/__tests__/core/discovery/topology.test.d.ts.map +1 -0
- package/dist/__tests__/core/discovery/topology.test.js +191 -0
- package/dist/__tests__/core/discovery/topology.test.js.map +1 -0
- package/dist/__tests__/core/failover/executor.test.d.ts +5 -0
- package/dist/__tests__/core/failover/executor.test.d.ts.map +1 -0
- package/dist/__tests__/core/failover/executor.test.js +256 -0
- package/dist/__tests__/core/failover/executor.test.js.map +1 -0
- package/dist/__tests__/core/monitoring/collector.test.d.ts +5 -0
- package/dist/__tests__/core/monitoring/collector.test.d.ts.map +1 -0
- package/dist/__tests__/core/monitoring/collector.test.js +131 -0
- package/dist/__tests__/core/monitoring/collector.test.js.map +1 -0
- package/dist/__tests__/core/monitoring/exporters.test.d.ts +5 -0
- package/dist/__tests__/core/monitoring/exporters.test.d.ts.map +1 -0
- package/dist/__tests__/core/monitoring/exporters.test.js +90 -0
- package/dist/__tests__/core/monitoring/exporters.test.js.map +1 -0
- package/dist/__tests__/core/routing/proxysql-manager.test.d.ts +5 -0
- package/dist/__tests__/core/routing/proxysql-manager.test.d.ts.map +1 -0
- package/dist/__tests__/core/routing/proxysql-manager.test.js +155 -0
- package/dist/__tests__/core/routing/proxysql-manager.test.js.map +1 -0
- package/dist/__tests__/types/index.test.d.ts +5 -0
- package/dist/__tests__/types/index.test.d.ts.map +1 -0
- package/dist/__tests__/types/index.test.js +290 -0
- package/dist/__tests__/types/index.test.js.map +1 -0
- package/dist/__tests__/utils/exceptions.test.d.ts +5 -0
- package/dist/__tests__/utils/exceptions.test.d.ts.map +1 -0
- package/dist/__tests__/utils/exceptions.test.js +142 -0
- package/dist/__tests__/utils/exceptions.test.js.map +1 -0
- package/dist/api/routes/clusters.d.ts +7 -0
- package/dist/api/routes/clusters.d.ts.map +1 -0
- package/dist/api/routes/clusters.js +123 -0
- package/dist/api/routes/clusters.js.map +1 -0
- package/dist/api/routes/config.d.ts +7 -0
- package/dist/api/routes/config.d.ts.map +1 -0
- package/dist/api/routes/config.js +65 -0
- package/dist/api/routes/config.js.map +1 -0
- package/dist/api/routes/failover.d.ts +7 -0
- package/dist/api/routes/failover.d.ts.map +1 -0
- package/dist/api/routes/failover.js +100 -0
- package/dist/api/routes/failover.js.map +1 -0
- package/dist/api/routes/instances.d.ts +11 -0
- package/dist/api/routes/instances.d.ts.map +1 -0
- package/dist/api/routes/instances.js +315 -0
- package/dist/api/routes/instances.js.map +1 -0
- package/dist/api/routes/monitoring.d.ts +7 -0
- package/dist/api/routes/monitoring.d.ts.map +1 -0
- package/dist/api/routes/monitoring.js +72 -0
- package/dist/api/routes/monitoring.js.map +1 -0
- package/dist/api/routes/webhooks.d.ts +12 -0
- package/dist/api/routes/webhooks.d.ts.map +1 -0
- package/dist/api/routes/webhooks.js +232 -0
- package/dist/api/routes/webhooks.js.map +1 -0
- package/dist/api/schemas/index.d.ts +965 -0
- package/dist/api/schemas/index.d.ts.map +1 -0
- package/dist/api/schemas/index.js +171 -0
- package/dist/api/schemas/index.js.map +1 -0
- package/dist/app.d.ts +13 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +197 -0
- package/dist/app.js.map +1 -0
- package/dist/bin/clawsql.d.ts +12 -0
- package/dist/bin/clawsql.d.ts.map +1 -0
- package/dist/bin/clawsql.js +43 -0
- package/dist/bin/clawsql.js.map +1 -0
- package/dist/cli/agent/handler.d.ts +73 -0
- package/dist/cli/agent/handler.d.ts.map +1 -0
- package/dist/cli/agent/handler.js +258 -0
- package/dist/cli/agent/handler.js.map +1 -0
- package/dist/cli/agent/index.d.ts +14 -0
- package/dist/cli/agent/index.d.ts.map +1 -0
- package/dist/cli/agent/index.js +30 -0
- package/dist/cli/agent/index.js.map +1 -0
- package/dist/cli/agent/openclaw-integration.d.ts +81 -0
- package/dist/cli/agent/openclaw-integration.d.ts.map +1 -0
- package/dist/cli/agent/openclaw-integration.js +341 -0
- package/dist/cli/agent/openclaw-integration.js.map +1 -0
- package/dist/cli/agent/providers/anthropic.d.ts +27 -0
- package/dist/cli/agent/providers/anthropic.d.ts.map +1 -0
- package/dist/cli/agent/providers/anthropic.js +106 -0
- package/dist/cli/agent/providers/anthropic.js.map +1 -0
- package/dist/cli/agent/providers/base.d.ts +91 -0
- package/dist/cli/agent/providers/base.d.ts.map +1 -0
- package/dist/cli/agent/providers/base.js +24 -0
- package/dist/cli/agent/providers/base.js.map +1 -0
- package/dist/cli/agent/providers/openai.d.ts +27 -0
- package/dist/cli/agent/providers/openai.d.ts.map +1 -0
- package/dist/cli/agent/providers/openai.js +98 -0
- package/dist/cli/agent/providers/openai.js.map +1 -0
- package/dist/cli/agent/tools/index.d.ts +32 -0
- package/dist/cli/agent/tools/index.d.ts.map +1 -0
- package/dist/cli/agent/tools/index.js +263 -0
- package/dist/cli/agent/tools/index.js.map +1 -0
- package/dist/cli/commands/cleanup.d.ts +12 -0
- package/dist/cli/commands/cleanup.d.ts.map +1 -0
- package/dist/cli/commands/cleanup.js +205 -0
- package/dist/cli/commands/cleanup.js.map +1 -0
- package/dist/cli/commands/clusters.d.ts +12 -0
- package/dist/cli/commands/clusters.d.ts.map +1 -0
- package/dist/cli/commands/clusters.js +468 -0
- package/dist/cli/commands/clusters.js.map +1 -0
- package/dist/cli/commands/config.d.ts +12 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +406 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/cron.d.ts +12 -0
- package/dist/cli/commands/cron.d.ts.map +1 -0
- package/dist/cli/commands/cron.js +215 -0
- package/dist/cli/commands/cron.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +13 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +687 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/failover.d.ts +16 -0
- package/dist/cli/commands/failover.d.ts.map +1 -0
- package/dist/cli/commands/failover.js +333 -0
- package/dist/cli/commands/failover.js.map +1 -0
- package/dist/cli/commands/health.d.ts +12 -0
- package/dist/cli/commands/health.d.ts.map +1 -0
- package/dist/cli/commands/health.js +125 -0
- package/dist/cli/commands/health.js.map +1 -0
- package/dist/cli/commands/help.d.ts +12 -0
- package/dist/cli/commands/help.d.ts.map +1 -0
- package/dist/cli/commands/help.js +52 -0
- package/dist/cli/commands/help.js.map +1 -0
- package/dist/cli/commands/instances.d.ts +12 -0
- package/dist/cli/commands/instances.d.ts.map +1 -0
- package/dist/cli/commands/instances.js +801 -0
- package/dist/cli/commands/instances.js.map +1 -0
- package/dist/cli/commands/notify.d.ts +12 -0
- package/dist/cli/commands/notify.d.ts.map +1 -0
- package/dist/cli/commands/notify.js +43 -0
- package/dist/cli/commands/notify.js.map +1 -0
- package/dist/cli/commands/sql.d.ts +12 -0
- package/dist/cli/commands/sql.d.ts.map +1 -0
- package/dist/cli/commands/sql.js +90 -0
- package/dist/cli/commands/sql.js.map +1 -0
- package/dist/cli/commands/start.d.ts +12 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +174 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +12 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +218 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/stop.d.ts +12 -0
- package/dist/cli/commands/stop.d.ts.map +1 -0
- package/dist/cli/commands/stop.js +128 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/commands/topology.d.ts +12 -0
- package/dist/cli/commands/topology.d.ts.map +1 -0
- package/dist/cli/commands/topology.js +106 -0
- package/dist/cli/commands/topology.js.map +1 -0
- package/dist/cli/completer.d.ts +47 -0
- package/dist/cli/completer.d.ts.map +1 -0
- package/dist/cli/completer.js +332 -0
- package/dist/cli/completer.js.map +1 -0
- package/dist/cli/formatter.d.ts +165 -0
- package/dist/cli/formatter.d.ts.map +1 -0
- package/dist/cli/formatter.js +408 -0
- package/dist/cli/formatter.js.map +1 -0
- package/dist/cli/index.d.ts +21 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +79 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/raw-input.d.ts +97 -0
- package/dist/cli/raw-input.d.ts.map +1 -0
- package/dist/cli/raw-input.js +493 -0
- package/dist/cli/raw-input.js.map +1 -0
- package/dist/cli/registry.d.ts +103 -0
- package/dist/cli/registry.d.ts.map +1 -0
- package/dist/cli/registry.js +205 -0
- package/dist/cli/registry.js.map +1 -0
- package/dist/cli/repl.d.ts +83 -0
- package/dist/cli/repl.d.ts.map +1 -0
- package/dist/cli/repl.js +447 -0
- package/dist/cli/repl.js.map +1 -0
- package/dist/cli/ui/components.d.ts +144 -0
- package/dist/cli/ui/components.d.ts.map +1 -0
- package/dist/cli/ui/components.js +331 -0
- package/dist/cli/ui/components.js.map +1 -0
- package/dist/cli/ui/index.d.ts +7 -0
- package/dist/cli/ui/index.d.ts.map +1 -0
- package/dist/cli/ui/index.js +23 -0
- package/dist/cli/ui/index.js.map +1 -0
- package/dist/cli/utils/docker-files.d.ts +39 -0
- package/dist/cli/utils/docker-files.d.ts.map +1 -0
- package/dist/cli/utils/docker-files.js +223 -0
- package/dist/cli/utils/docker-files.js.map +1 -0
- package/dist/cli/utils/docker-prereq.d.ts +48 -0
- package/dist/cli/utils/docker-prereq.d.ts.map +1 -0
- package/dist/cli/utils/docker-prereq.js +203 -0
- package/dist/cli/utils/docker-prereq.js.map +1 -0
- package/dist/config/settings.d.ts +594 -0
- package/dist/config/settings.d.ts.map +1 -0
- package/dist/config/settings.js +250 -0
- package/dist/config/settings.js.map +1 -0
- package/dist/core/discovery/cluster-view.d.ts +50 -0
- package/dist/core/discovery/cluster-view.d.ts.map +1 -0
- package/dist/core/discovery/cluster-view.js +235 -0
- package/dist/core/discovery/cluster-view.js.map +1 -0
- package/dist/core/discovery/scanner.d.ts +70 -0
- package/dist/core/discovery/scanner.d.ts.map +1 -0
- package/dist/core/discovery/scanner.js +197 -0
- package/dist/core/discovery/scanner.js.map +1 -0
- package/dist/core/discovery/topology.d.ts +118 -0
- package/dist/core/discovery/topology.d.ts.map +1 -0
- package/dist/core/discovery/topology.js +550 -0
- package/dist/core/discovery/topology.js.map +1 -0
- package/dist/core/failover/candidate-selector.d.ts +46 -0
- package/dist/core/failover/candidate-selector.d.ts.map +1 -0
- package/dist/core/failover/candidate-selector.js +70 -0
- package/dist/core/failover/candidate-selector.js.map +1 -0
- package/dist/core/failover/executor.d.ts +104 -0
- package/dist/core/failover/executor.d.ts.map +1 -0
- package/dist/core/failover/executor.js +248 -0
- package/dist/core/failover/executor.js.map +1 -0
- package/dist/core/failover/operation-builder.d.ts +71 -0
- package/dist/core/failover/operation-builder.d.ts.map +1 -0
- package/dist/core/failover/operation-builder.js +157 -0
- package/dist/core/failover/operation-builder.js.map +1 -0
- package/dist/core/failover/operation-runner.d.ts +75 -0
- package/dist/core/failover/operation-runner.d.ts.map +1 -0
- package/dist/core/failover/operation-runner.js +191 -0
- package/dist/core/failover/operation-runner.js.map +1 -0
- package/dist/core/failover/promoter.d.ts +33 -0
- package/dist/core/failover/promoter.d.ts.map +1 -0
- package/dist/core/failover/promoter.js +97 -0
- package/dist/core/failover/promoter.js.map +1 -0
- package/dist/core/failover/recovery-manager.d.ts +47 -0
- package/dist/core/failover/recovery-manager.d.ts.map +1 -0
- package/dist/core/failover/recovery-manager.js +145 -0
- package/dist/core/failover/recovery-manager.js.map +1 -0
- package/dist/core/failover/types.d.ts +54 -0
- package/dist/core/failover/types.d.ts.map +1 -0
- package/dist/core/failover/types.js +8 -0
- package/dist/core/failover/types.js.map +1 -0
- package/dist/core/monitoring/collector.d.ts +25 -0
- package/dist/core/monitoring/collector.d.ts.map +1 -0
- package/dist/core/monitoring/collector.js +115 -0
- package/dist/core/monitoring/collector.js.map +1 -0
- package/dist/core/monitoring/exporters.d.ts +49 -0
- package/dist/core/monitoring/exporters.d.ts.map +1 -0
- package/dist/core/monitoring/exporters.js +126 -0
- package/dist/core/monitoring/exporters.js.map +1 -0
- package/dist/core/routing/proxysql-manager.d.ts +213 -0
- package/dist/core/routing/proxysql-manager.d.ts.map +1 -0
- package/dist/core/routing/proxysql-manager.js +632 -0
- package/dist/core/routing/proxysql-manager.js.map +1 -0
- package/dist/core/sync/replica-recovery.d.ts +40 -0
- package/dist/core/sync/replica-recovery.d.ts.map +1 -0
- package/dist/core/sync/replica-recovery.js +134 -0
- package/dist/core/sync/replica-recovery.js.map +1 -0
- package/dist/core/sync/sync-coordinator.d.ts +83 -0
- package/dist/core/sync/sync-coordinator.d.ts.map +1 -0
- package/dist/core/sync/sync-coordinator.js +254 -0
- package/dist/core/sync/sync-coordinator.js.map +1 -0
- package/dist/core/sync/topology-watcher.d.ts +76 -0
- package/dist/core/sync/topology-watcher.d.ts.map +1 -0
- package/dist/core/sync/topology-watcher.js +222 -0
- package/dist/core/sync/topology-watcher.js.map +1 -0
- package/dist/core/sync/types.d.ts +85 -0
- package/dist/core/sync/types.d.ts.map +1 -0
- package/dist/core/sync/types.js +8 -0
- package/dist/core/sync/types.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +212 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +153 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/database.d.ts +62 -0
- package/dist/utils/database.d.ts.map +1 -0
- package/dist/utils/database.js +257 -0
- package/dist/utils/database.js.map +1 -0
- package/dist/utils/exceptions.d.ts +69 -0
- package/dist/utils/exceptions.d.ts.map +1 -0
- package/dist/utils/exceptions.js +121 -0
- package/dist/utils/exceptions.js.map +1 -0
- package/dist/utils/logger.d.ts +20 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +90 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/mysql-client.d.ts +43 -0
- package/dist/utils/mysql-client.d.ts.map +1 -0
- package/dist/utils/mysql-client.js +125 -0
- package/dist/utils/mysql-client.js.map +1 -0
- package/docker/Dockerfile +61 -0
- package/docker/Dockerfile.node +41 -0
- package/docker/grafana/dashboards/clawsql.json +212 -0
- package/docker/grafana/provisioning/dashboards/dashboards.yml +13 -0
- package/docker/grafana/provisioning/datasources/datasources.yml +12 -0
- package/docker/init/primary.sql +26 -0
- package/docker/init/replica.sql +16 -0
- package/docker/orchestrator/orchestrator.conf.json +98 -0
- package/docker/prometheus/prometheus.yml +45 -0
- package/docker/proxysql/entrypoint.sh +8 -0
- package/docker/proxysql/init.sql.demo +30 -0
- package/docker/proxysql/proxysql.cnf +38 -0
- package/docker-compose.demo.yml +115 -0
- package/docker-compose.yml +217 -0
- package/init/primary.sql +19 -0
- package/init/replica.sql +13 -0
- package/package.json +84 -0
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ClawSQL - Orchestrator Client
|
|
4
|
+
*
|
|
5
|
+
* Client for interacting with Orchestrator API for topology management.
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.OrchestratorClient = void 0;
|
|
12
|
+
exports.getOrchestratorClient = getOrchestratorClient;
|
|
13
|
+
const axios_1 = __importDefault(require("axios"));
|
|
14
|
+
const logger_js_1 = require("../../utils/logger.js");
|
|
15
|
+
const index_js_1 = require("../../types/index.js");
|
|
16
|
+
const exceptions_js_1 = require("../../utils/exceptions.js");
|
|
17
|
+
const logger = (0, logger_js_1.getLogger)('orchestrator');
|
|
18
|
+
/**
|
|
19
|
+
* Orchestrator API client
|
|
20
|
+
*/
|
|
21
|
+
class OrchestratorClient {
|
|
22
|
+
client;
|
|
23
|
+
baseUrl;
|
|
24
|
+
constructor(settings) {
|
|
25
|
+
const config = settings || {
|
|
26
|
+
url: 'http://orchestrator:3000',
|
|
27
|
+
timeout: 30.0,
|
|
28
|
+
};
|
|
29
|
+
this.baseUrl = config.url.replace(/\/$/, '');
|
|
30
|
+
this.client = axios_1.default.create({
|
|
31
|
+
baseURL: this.baseUrl,
|
|
32
|
+
timeout: config.timeout * 1000,
|
|
33
|
+
headers: {
|
|
34
|
+
'Content-Type': 'application/json',
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
logger.debug({ url: this.baseUrl }, 'Orchestrator client initialized');
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get cluster name for an instance
|
|
41
|
+
* Uses the instance's cluster name or derives it from the cluster alias
|
|
42
|
+
*/
|
|
43
|
+
async getClusterForInstance(host, port = 3306) {
|
|
44
|
+
try {
|
|
45
|
+
const response = await this.client.get(`/api/instance/${host}/${port}`);
|
|
46
|
+
const data = response.data;
|
|
47
|
+
// Try to get cluster name from response
|
|
48
|
+
const clusterName = data.ClusterName || data.cluster_alias || data.Alias;
|
|
49
|
+
if (clusterName) {
|
|
50
|
+
return clusterName;
|
|
51
|
+
}
|
|
52
|
+
// Fallback: if this is a primary, use its hostname as cluster name
|
|
53
|
+
const masterKey = data.MasterKey;
|
|
54
|
+
const replicationDepth = data.ReplicationDepth;
|
|
55
|
+
const isPrimary = (masterKey && !masterKey.Hostname) ||
|
|
56
|
+
(replicationDepth !== undefined && replicationDepth === 0) ||
|
|
57
|
+
data.IsPrimary;
|
|
58
|
+
if (isPrimary) {
|
|
59
|
+
return host;
|
|
60
|
+
}
|
|
61
|
+
// For replicas, get the cluster from the primary/master
|
|
62
|
+
if (masterKey && masterKey.Hostname) {
|
|
63
|
+
return masterKey.Hostname;
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
if (axios_1.default.isAxiosError(error) && error.response?.status === 404) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
logger.error({ error, host, port }, 'Failed to get cluster for instance');
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if Orchestrator is healthy
|
|
77
|
+
*/
|
|
78
|
+
async healthCheck() {
|
|
79
|
+
try {
|
|
80
|
+
const response = await this.client.get('/api/health');
|
|
81
|
+
return response.status === 200;
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get all known cluster names
|
|
89
|
+
*/
|
|
90
|
+
async getClusters() {
|
|
91
|
+
try {
|
|
92
|
+
const response = await this.client.get('/api/clusters');
|
|
93
|
+
return response.data.map((c) => typeof c === 'string' ? c : c.cluster_name || '').filter(Boolean);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
throw new exceptions_js_1.OrchestratorError('Failed to get clusters', { error });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get all clusters with resolved topology info
|
|
101
|
+
* Returns cluster info with better naming
|
|
102
|
+
*/
|
|
103
|
+
async getAllClustersWithInfo() {
|
|
104
|
+
try {
|
|
105
|
+
const clusterNames = await this.getClusters();
|
|
106
|
+
const result = [];
|
|
107
|
+
for (const clusterName of clusterNames) {
|
|
108
|
+
const topology = await this.getTopology(clusterName);
|
|
109
|
+
if (topology) {
|
|
110
|
+
// Derive a better display name
|
|
111
|
+
let displayName = clusterName;
|
|
112
|
+
// Strip port from cluster name for display
|
|
113
|
+
if (clusterName.includes(':')) {
|
|
114
|
+
displayName = clusterName.split(':')[0];
|
|
115
|
+
}
|
|
116
|
+
// Use the actual primary's hostname if available
|
|
117
|
+
const primaryHost = topology.primary?.host || clusterName.split(':')[0];
|
|
118
|
+
const primaryPort = topology.primary?.port || 3306;
|
|
119
|
+
result.push({
|
|
120
|
+
clusterName,
|
|
121
|
+
displayName,
|
|
122
|
+
primaryHost,
|
|
123
|
+
primaryPort,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
throw new exceptions_js_1.OrchestratorError('Failed to get clusters with info', { error });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get topology for a specific cluster
|
|
135
|
+
*/
|
|
136
|
+
async getTopology(clusterName) {
|
|
137
|
+
try {
|
|
138
|
+
const response = await this.client.get(`/api/cluster/${clusterName}`);
|
|
139
|
+
// Handle both array and object responses
|
|
140
|
+
if (Array.isArray(response.data)) {
|
|
141
|
+
return this.parseTopologyFromArray(response.data, clusterName);
|
|
142
|
+
}
|
|
143
|
+
return this.parseTopology(response.data, clusterName);
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
if (axios_1.default.isAxiosError(error) && error.response?.status === 404) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
throw new exceptions_js_1.OrchestratorError(`Failed to get topology for ${clusterName}`, { error });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Get instance details
|
|
154
|
+
*/
|
|
155
|
+
async getInstance(host, port = 3306) {
|
|
156
|
+
try {
|
|
157
|
+
const response = await this.client.get(`/api/instance/${host}/${port}`);
|
|
158
|
+
return this.parseInstance(response.data);
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
if (axios_1.default.isAxiosError(error) && error.response?.status === 404) {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
throw new exceptions_js_1.OrchestratorError(`Failed to get instance ${host}:${port}`, { error });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Force Orchestrator to discover an instance
|
|
169
|
+
*/
|
|
170
|
+
async discoverInstance(host, port = 3306) {
|
|
171
|
+
try {
|
|
172
|
+
// Orchestrator uses GET for discover, not POST
|
|
173
|
+
await this.client.get(`/api/discover/${host}/${port}`);
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
logger.error({ error, host, port }, 'Failed to discover instance');
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Remove instance from Orchestrator's memory
|
|
183
|
+
*/
|
|
184
|
+
async forgetInstance(host, port = 3306) {
|
|
185
|
+
try {
|
|
186
|
+
// Orchestrator uses GET for forget, not POST
|
|
187
|
+
await this.client.get(`/api/forget/${host}/${port}`);
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
logger.error({ error, host, port }, 'Failed to forget instance');
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Put instance in maintenance mode
|
|
197
|
+
*/
|
|
198
|
+
async beginMaintenance(host, port, reason, durationMinutes = 60) {
|
|
199
|
+
try {
|
|
200
|
+
await this.client.post(`/api/maintenance-begin/${host}/${port}`, {
|
|
201
|
+
reason,
|
|
202
|
+
duration: `${durationMinutes}m`,
|
|
203
|
+
});
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
logger.error({ error, host, port }, 'Failed to begin maintenance');
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Remove instance from maintenance mode
|
|
213
|
+
*/
|
|
214
|
+
async endMaintenance(host, port) {
|
|
215
|
+
try {
|
|
216
|
+
// Orchestrator uses GET method for end-downtime endpoint
|
|
217
|
+
await this.client.get(`/api/end-downtime/${host}/${port}`);
|
|
218
|
+
logger.info({ host, port }, 'Instance removed from maintenance');
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
logger.error({ error, host, port }, 'Failed to end maintenance');
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Get replication analysis
|
|
228
|
+
*/
|
|
229
|
+
async getReplicationAnalysis() {
|
|
230
|
+
try {
|
|
231
|
+
const response = await this.client.get('/api/replication-analysis');
|
|
232
|
+
return response.data;
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
throw new exceptions_js_1.OrchestratorError('Failed to get replication analysis', { error });
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Graceful master takeover - promotes a replica to master (switchover)
|
|
240
|
+
* Uses cluster alias, orchestrator selects the best replica
|
|
241
|
+
*/
|
|
242
|
+
async gracefulMasterTakeover(clusterAlias, destinationHost, destinationPort) {
|
|
243
|
+
try {
|
|
244
|
+
let url = `/api/graceful-master-takeover-auto/${clusterAlias}`;
|
|
245
|
+
if (destinationHost && destinationPort) {
|
|
246
|
+
url = `/api/graceful-master-takeover/${clusterAlias}/${destinationHost}/${destinationPort}`;
|
|
247
|
+
}
|
|
248
|
+
// Orchestrator uses GET for these operations, not POST
|
|
249
|
+
const response = await this.client.get(url);
|
|
250
|
+
return response.data;
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
// Extract more detailed error message
|
|
254
|
+
let message = `Failed graceful master takeover for ${clusterAlias}`;
|
|
255
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
256
|
+
const data = error.response?.data;
|
|
257
|
+
if (data) {
|
|
258
|
+
if (data.Message) {
|
|
259
|
+
message = data.Message;
|
|
260
|
+
}
|
|
261
|
+
else if (data.Error) {
|
|
262
|
+
message = data.Error;
|
|
263
|
+
}
|
|
264
|
+
else if (typeof data === 'string') {
|
|
265
|
+
message = data;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (error.response?.status === 500) {
|
|
269
|
+
logger.error({ clusterAlias, status: error.response.status, data }, 'Orchestrator 500 error');
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
throw new exceptions_js_1.OrchestratorError(message, { error, clusterAlias });
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Force master failover - forcefully promotes a replica when master is down
|
|
277
|
+
* Uses cluster alias, orchestrator selects the best replica
|
|
278
|
+
*/
|
|
279
|
+
async forceMasterFailover(clusterAlias) {
|
|
280
|
+
try {
|
|
281
|
+
const url = `/api/force-master-failover/${clusterAlias}`;
|
|
282
|
+
// Orchestrator uses GET for these operations, not POST
|
|
283
|
+
const response = await this.client.get(url);
|
|
284
|
+
return response.data;
|
|
285
|
+
}
|
|
286
|
+
catch (error) {
|
|
287
|
+
throw new exceptions_js_1.OrchestratorError(`Failed force master failover for ${clusterAlias}`, { error });
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Relocate replicas to follow a new primary
|
|
292
|
+
*/
|
|
293
|
+
async relocateReplicas(host, port, destinationHost, destinationPort) {
|
|
294
|
+
try {
|
|
295
|
+
// Orchestrator uses GET for relocate operations
|
|
296
|
+
await this.client.get(`/api/relocate/${host}/${port}/${destinationHost}/${destinationPort}`);
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
logger.error({ error, host, port, destinationHost, destinationPort }, 'Failed to relocate replicas');
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Set instance as read-only
|
|
306
|
+
*/
|
|
307
|
+
async setReadOnly(host, port) {
|
|
308
|
+
try {
|
|
309
|
+
await this.client.get(`/api/set-read-only/${host}/${port}`);
|
|
310
|
+
logger.info({ host, port }, 'Instance set to read-only');
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
logger.error({ error, host, port }, 'Failed to set read-only');
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Set instance as writeable
|
|
320
|
+
*/
|
|
321
|
+
async setWriteable(host, port) {
|
|
322
|
+
try {
|
|
323
|
+
await this.client.get(`/api/set-writeable/${host}/${port}`);
|
|
324
|
+
logger.info({ host, port }, 'Instance set to writeable');
|
|
325
|
+
return true;
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
logger.error({ error, host, port }, 'Failed to set writeable');
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Start replication on an instance
|
|
334
|
+
*/
|
|
335
|
+
async startSlave(host, port) {
|
|
336
|
+
try {
|
|
337
|
+
await this.client.get(`/api/start-slave/${host}/${port}`);
|
|
338
|
+
logger.info({ host, port }, 'Replication started');
|
|
339
|
+
return true;
|
|
340
|
+
}
|
|
341
|
+
catch (error) {
|
|
342
|
+
logger.error({ error, host, port }, 'Failed to start replication');
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Stop replication on an instance
|
|
348
|
+
*/
|
|
349
|
+
async stopSlave(host, port) {
|
|
350
|
+
try {
|
|
351
|
+
await this.client.get(`/api/stop-slave/${host}/${port}`);
|
|
352
|
+
logger.info({ host, port }, 'Replication stopped');
|
|
353
|
+
return true;
|
|
354
|
+
}
|
|
355
|
+
catch (error) {
|
|
356
|
+
logger.error({ error, host, port }, 'Failed to stop replication');
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Reset replication on an instance
|
|
362
|
+
*/
|
|
363
|
+
async resetSlave(host, port) {
|
|
364
|
+
try {
|
|
365
|
+
await this.client.get(`/api/reset-slave/${host}/${port}`);
|
|
366
|
+
logger.info({ host, port }, 'Replication reset');
|
|
367
|
+
return true;
|
|
368
|
+
}
|
|
369
|
+
catch (error) {
|
|
370
|
+
logger.error({ error, host, port }, 'Failed to reset replication');
|
|
371
|
+
return false;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Parse Orchestrator topology response into MySQLCluster
|
|
376
|
+
*/
|
|
377
|
+
parseTopology(data, clusterName) {
|
|
378
|
+
// Try to get cluster alias for friendly display name
|
|
379
|
+
// ClusterAlias is user-configured, SuggestedClusterAlias is auto-generated from primary hostname
|
|
380
|
+
const clusterAlias = data.ClusterAlias ||
|
|
381
|
+
data.SuggestedClusterAlias;
|
|
382
|
+
const displayName = clusterAlias || clusterName;
|
|
383
|
+
const cluster = (0, index_js_1.createMySQLCluster)(clusterName, displayName);
|
|
384
|
+
// Check if this is an instance node
|
|
385
|
+
if (data.Alias) {
|
|
386
|
+
const instance = this.parseInstance(data);
|
|
387
|
+
if (instance && instance.role === index_js_1.InstanceRole.PRIMARY) {
|
|
388
|
+
cluster.primary = instance;
|
|
389
|
+
}
|
|
390
|
+
else if (instance) {
|
|
391
|
+
cluster.replicas.push(instance);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
// Parse children/replicas
|
|
395
|
+
const children = data.Child;
|
|
396
|
+
if (children) {
|
|
397
|
+
for (const child of children) {
|
|
398
|
+
const instance = this.parseInstance(child);
|
|
399
|
+
if (instance) {
|
|
400
|
+
cluster.replicas.push(instance);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
// Parse replicas if in different format
|
|
405
|
+
const replicas = data.replicas;
|
|
406
|
+
if (replicas) {
|
|
407
|
+
for (const replicaData of replicas) {
|
|
408
|
+
const instance = this.parseInstance(replicaData);
|
|
409
|
+
if (instance) {
|
|
410
|
+
cluster.replicas.push(instance);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return cluster;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Parse Orchestrator cluster array response into MySQLCluster
|
|
418
|
+
* The /api/cluster/{name} endpoint returns a flat array of instances
|
|
419
|
+
*/
|
|
420
|
+
parseTopologyFromArray(instances, clusterName) {
|
|
421
|
+
// Try to get the actual cluster name and alias from instance data
|
|
422
|
+
let actualClusterName = clusterName;
|
|
423
|
+
let clusterAlias = '';
|
|
424
|
+
if (instances.length > 0) {
|
|
425
|
+
// ClusterName is the canonical identifier (hostname:port)
|
|
426
|
+
if (instances[0].ClusterName) {
|
|
427
|
+
actualClusterName = instances[0].ClusterName;
|
|
428
|
+
}
|
|
429
|
+
// ClusterAlias is the user-friendly name configured in Orchestrator
|
|
430
|
+
// SuggestedClusterAlias is auto-generated from the primary hostname
|
|
431
|
+
clusterAlias = instances[0].ClusterAlias ||
|
|
432
|
+
instances[0].SuggestedClusterAlias || '';
|
|
433
|
+
}
|
|
434
|
+
// Use clusterAlias as display name if available, otherwise use clusterName
|
|
435
|
+
const displayName = clusterAlias || actualClusterName;
|
|
436
|
+
const cluster = (0, index_js_1.createMySQLCluster)(actualClusterName, displayName);
|
|
437
|
+
for (const instanceData of instances) {
|
|
438
|
+
const instance = this.parseInstance(instanceData);
|
|
439
|
+
if (instance) {
|
|
440
|
+
// Update instance clusterId to match
|
|
441
|
+
instance.clusterId = actualClusterName;
|
|
442
|
+
// Primary is identified by having no master (MasterKey.Hostname is empty)
|
|
443
|
+
// or ReplicationDepth === 0
|
|
444
|
+
const masterKey = instanceData.MasterKey;
|
|
445
|
+
const replicationDepth = instanceData.ReplicationDepth;
|
|
446
|
+
const isPrimary = (masterKey && !masterKey.Hostname) ||
|
|
447
|
+
(replicationDepth !== undefined && replicationDepth === 0);
|
|
448
|
+
if (isPrimary) {
|
|
449
|
+
cluster.primary = instance;
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
cluster.replicas.push(instance);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return cluster;
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Parse Orchestrator instance data into MySQLInstance
|
|
460
|
+
*/
|
|
461
|
+
parseInstance(data) {
|
|
462
|
+
if (!data)
|
|
463
|
+
return null;
|
|
464
|
+
// Determine role - check multiple indicators
|
|
465
|
+
let role = index_js_1.InstanceRole.UNKNOWN;
|
|
466
|
+
// Primary indicators (in order of reliability):
|
|
467
|
+
// 1. IsPrimary flag (if available)
|
|
468
|
+
// 2. IsCoPrimary flag (for co-primary setups)
|
|
469
|
+
// 3. No master (MasterKey.Hostname is empty) and replication depth is 0
|
|
470
|
+
const masterKey = data.MasterKey;
|
|
471
|
+
const replicationDepth = data.ReplicationDepth;
|
|
472
|
+
if (data.IsPrimary || data.IsCoPrimary) {
|
|
473
|
+
role = index_js_1.InstanceRole.PRIMARY;
|
|
474
|
+
}
|
|
475
|
+
else if (data.IsReplica) {
|
|
476
|
+
role = index_js_1.InstanceRole.REPLICA;
|
|
477
|
+
}
|
|
478
|
+
else if (masterKey && !masterKey.Hostname) {
|
|
479
|
+
// No master means this is the primary
|
|
480
|
+
role = index_js_1.InstanceRole.PRIMARY;
|
|
481
|
+
}
|
|
482
|
+
else if (replicationDepth !== undefined && replicationDepth === 0) {
|
|
483
|
+
// Replication depth 0 means this is the primary
|
|
484
|
+
role = index_js_1.InstanceRole.PRIMARY;
|
|
485
|
+
}
|
|
486
|
+
else if (masterKey && masterKey.Hostname) {
|
|
487
|
+
// Has a master, so it's a replica
|
|
488
|
+
role = index_js_1.InstanceRole.REPLICA;
|
|
489
|
+
}
|
|
490
|
+
// Determine state
|
|
491
|
+
let state = index_js_1.InstanceState.OFFLINE;
|
|
492
|
+
// IsLastCheckValid is the actual health check result
|
|
493
|
+
// IsUpToDate just means Orchestrator has recent data for this instance
|
|
494
|
+
if (data.IsLastCheckValid === true) {
|
|
495
|
+
state = index_js_1.InstanceState.ONLINE;
|
|
496
|
+
}
|
|
497
|
+
// Handle maintenance mode
|
|
498
|
+
if (data.in_maintenance || data.IsDowntimed) {
|
|
499
|
+
state = index_js_1.InstanceState.MAINTENANCE;
|
|
500
|
+
}
|
|
501
|
+
// Get host and port
|
|
502
|
+
const key = data.Key;
|
|
503
|
+
const host = (data.Hostname || key?.Hostname || '');
|
|
504
|
+
const port = (data.Port || key?.Port || 3306);
|
|
505
|
+
if (!host)
|
|
506
|
+
return null;
|
|
507
|
+
// Extract replication lag - Orchestrator returns {Int64, Valid} object
|
|
508
|
+
let replicationLag;
|
|
509
|
+
const lagData = data.ReplicationLagSeconds;
|
|
510
|
+
if (lagData && typeof lagData === 'object' && 'Int64' in lagData) {
|
|
511
|
+
replicationLag = lagData.Int64;
|
|
512
|
+
}
|
|
513
|
+
else if (typeof data.ReplicationLagSeconds === 'number') {
|
|
514
|
+
replicationLag = data.ReplicationLagSeconds;
|
|
515
|
+
}
|
|
516
|
+
return (0, index_js_1.createMySQLInstance)(host, port, {
|
|
517
|
+
serverId: data.ServerID,
|
|
518
|
+
role,
|
|
519
|
+
state,
|
|
520
|
+
version: data.Version,
|
|
521
|
+
replicationLag,
|
|
522
|
+
lastSeen: state === index_js_1.InstanceState.ONLINE ? new Date() : new Date(0),
|
|
523
|
+
clusterId: data.ClusterName,
|
|
524
|
+
labels: {
|
|
525
|
+
alias: data.Alias || '',
|
|
526
|
+
dataCenter: data.DataCenter || '',
|
|
527
|
+
environment: data.Environment || '',
|
|
528
|
+
},
|
|
529
|
+
extra: {
|
|
530
|
+
isCoPrimary: data.IsCoPrimary || false,
|
|
531
|
+
isDetachedPrimary: data.IsDetachedPrimary || false,
|
|
532
|
+
replicationDepth: data.ReplicationDepth || 0,
|
|
533
|
+
},
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
exports.OrchestratorClient = OrchestratorClient;
|
|
538
|
+
// Singleton instance
|
|
539
|
+
let orchestratorClient = null;
|
|
540
|
+
/**
|
|
541
|
+
* Get the Orchestrator client instance
|
|
542
|
+
*/
|
|
543
|
+
function getOrchestratorClient() {
|
|
544
|
+
if (!orchestratorClient) {
|
|
545
|
+
const { getSettings } = require('../../config/settings.js');
|
|
546
|
+
orchestratorClient = new OrchestratorClient(getSettings().orchestrator);
|
|
547
|
+
}
|
|
548
|
+
return orchestratorClient;
|
|
549
|
+
}
|
|
550
|
+
//# sourceMappingURL=topology.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topology.js","sourceRoot":"","sources":["../../../src/core/discovery/topology.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ClawSQL - Candidate Selector
|
|
3
|
+
*
|
|
4
|
+
* Selects the best candidate for promotion during failover.
|
|
5
|
+
* Implements the Strategy Pattern for different selection strategies.
|
|
6
|
+
*/
|
|
7
|
+
import { MySQLCluster, MySQLInstance } from '../../types/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Candidate selection strategy
|
|
10
|
+
*/
|
|
11
|
+
export interface SelectionStrategy {
|
|
12
|
+
select(replicas: MySQLInstance[]): MySQLInstance | null;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Default selection strategy
|
|
16
|
+
* Selects the replica with lowest replication lag among healthy instances.
|
|
17
|
+
*/
|
|
18
|
+
export declare class LowestLagStrategy implements SelectionStrategy {
|
|
19
|
+
select(replicas: MySQLInstance[]): MySQLInstance | null;
|
|
20
|
+
private isHealthy;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Candidate Selector
|
|
24
|
+
* Handles the selection of the best replica to promote.
|
|
25
|
+
*/
|
|
26
|
+
export declare class CandidateSelector {
|
|
27
|
+
private strategy;
|
|
28
|
+
constructor(strategy?: SelectionStrategy);
|
|
29
|
+
/**
|
|
30
|
+
* Select the best candidate from cluster replicas
|
|
31
|
+
*/
|
|
32
|
+
select(cluster: MySQLCluster): MySQLInstance | null;
|
|
33
|
+
/**
|
|
34
|
+
* Find a specific replica by ID
|
|
35
|
+
*/
|
|
36
|
+
static findReplica(cluster: MySQLCluster, targetId: string): MySQLInstance | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Get instance ID string
|
|
39
|
+
*/
|
|
40
|
+
static getInstanceId(instance: MySQLInstance): string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Default selector instance
|
|
44
|
+
*/
|
|
45
|
+
export declare const candidateSelector: CandidateSelector;
|
|
46
|
+
//# sourceMappingURL=candidate-selector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"candidate-selector.d.ts","sourceRoot":"","sources":["../../../src/core/failover/candidate-selector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAiB,MAAM,sBAAsB,CAAC;AAElF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,aAAa,GAAG,IAAI,CAAC;CACzD;AAED;;;GAGG;AACH,qBAAa,iBAAkB,YAAW,iBAAiB;IACzD,MAAM,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,aAAa,GAAG,IAAI;IAmBvD,OAAO,CAAC,SAAS;CAGlB;AAED;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAoB;gBAExB,QAAQ,CAAC,EAAE,iBAAiB;IAIxC;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,YAAY,GAAG,aAAa,GAAG,IAAI;IAOnD;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAMtF;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM;CAGtD;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,mBAA0B,CAAC"}
|