How DCS_FunTester Adds Groovy Script Support and Master/Slave Registration
This article explains the recent updates to the DCS_FunTester distributed performance‑testing framework, including Groovy script execution, a new master‑slave registration mechanism, service‑layer extraction, and synchronization logic, while providing concrete Java code examples for each enhancement.
Adding Scheme 3 – Groovy Script Execution
The update introduces support for executing test cases written as Groovy scripts on both master and slave nodes. Apart from the existing access‑validation feature, script content is currently not filtered.
Master Node Implementation
@Override
int runScript(GroovyScript script) {
def mark = SourceCode.getMark()
def num = script.getMark()
def hosts = NodeData.getRunHost(num)
try {
hosts.each {
script.setMark(mark)
def re = MasterManager.runRequest(it, script)
if (!re) FailException.fail()
NodeData.addTask(it, mark)
}
} catch (FailException e) {
hosts.each { f -> MasterManager.stop(f) }
FailException.fail("Multiple node execution failed!")
}
mark
}Slave Node Implementation
@Override
public void runScript(GroovyScript script) {
ExecuteGroovy.executeScript(script.getScript());
}A placeholder params field is kept for future script‑parameter configuration.
Registration Mechanism
A simple registration class NodeData is added to manage node status, run information, results, timestamps, and task IDs. Key methods include: register(String host, boolean s) – registers a node and marks it. available() – returns a list of currently available nodes. mark(String host) – records the node's timestamp. check() – removes expired nodes and stale data based on configurable thresholds. addRunInfo(RunInfoBean bean), addResult(int mark, PerformanceResultBean bean), addTask(String host, Integer mark) – manage runtime metadata. getRunHost(int num) – selects a specified number of nodes, marks them as busy, and returns their addresses.
The design anticipates future integration with Redis or other mature components for persistent node information.
Canceling Direct Slave Access
After registration, the master node exclusively assigns tasks, eliminating direct slave node access. Some legacy interfaces (e.g., Swagger endpoints) remain, and two utility functions—refreshing master node info and re‑registering nodes—are kept for error recovery.
Service Layer Extraction
Static utility methods are refactored into a service interface IRunService with the following operations:
package com.funtester.master.service;
import com.funtester.slave.common.bean.run.GroovyScript;
import com.funtester.slave.common.bean.run.HttpRequest;
import com.funtester.slave.common.bean.run.HttpRequests;
import com.funtester.slave.common.bean.run.LocalMethod;
import com.funtester.slave.common.bean.run.ManyRequest;
interface IRunService {
int runRequest(HttpRequest request);
int runRequests(HttpRequests request);
int runMethod(LocalMethod method);
int runScript(GroovyScript script);
}Each request object carries a mark attribute: for the master node it represents the number of execution nodes, while for a slave node it identifies the specific task.
Synchronization Workflow
Start the master node.
Start a slave node, which contacts the master to obtain its own IP configuration.
The slave periodically synchronizes its status back to the master.
The implementation avoids using low‑level socket APIs, preferring higher‑level HTTP communication.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
