mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-10-21 05:40:14 +00:00
* chore: adopt qwen-code-checks.xml and fix all checkstyle violations
Add qwen-code-checks.xml (based on alibaba/fastjson2 convention) with
ImportOrder enabled (groups *,javax,java; static at bottom). Enable
includeTestSourceDirectory so both main and test sources are checked.
Fix all 869 violations across src/main/java and src/test/java:
- Reorder imports to *,javax,java groups with static-at-bottom
- Remove unused imports
- Normalize control statements (if/for/while/do/else/try-catch-finally)
to multiline braced form
- Fix indentation to match expected levels
- Split multiple statements per line
- Fix whitespace around braces, annotation style, and DOT spacing
mvn checkstyle:check -> BUILD SUCCESS, 0 violations
mvn test-compile -> EXIT 0
* fix(sdk-java): repair the checkstyle rewrite and satisfy qwen-code-checks.xml
Two mechanical passes in the original rewrite were wrong, and neither was
caught because the verification in the description never actually ran.
The control-flow pass inserted braces around wrapped expression
continuations, treating a ternary, a cast, a string concatenation or a
constructor call in a ternary branch as a braceless if/for body. That left
the module unparseable: javac reports 809 syntax errors across the module,
while the same sources on the merge base parse clean.
The import pass was not anchored at column 0, so it reached inside a Java
text block, treated the embedded TypeScript import as an unused Java
import, and deleted the class declaration, a field and a live ObjectMapper
import along with it.
Each spurious brace is undone only when doing so strictly lowers javac's
syntax error count for that file, which keeps the insertions NeedBraces
genuinely requires; nested constructs converge one level per pass. The
text-block file is rebuilt from the merge base and reordered by a
column-0-anchored pass that refuses to rewrite a block holding anything it
does not recognise.
The remaining violations are then cleared: imports into the *,javax,java
groups, whitespace from checkstyle's own line:col so no edit can land in a
literal or comment, and the two places where the ruleset has no mechanical
solution -- an empty switch-arrow block, where RegexpMultiline forbids
"-> { }" and WhitespaceAround forbids "-> {}", so the no-op default arm is
dropped; and a switch expression directly after "(", where ParenPad and
WhitespaceAround contradict, so it moves into a local.
checkstyle:check goes from unparseable to 0 violations, against 1835 on the
merge base under this ruleset. javac is clean, test-compile succeeds, and a
token-level audit against the merge base -- literals and comments compared
verbatim, braces and whitespace ignored -- shows no difference outside the
six edits this message names.
* ci(sdk-java): gate managed-agent-server checkstyle in the fast lane
qwen-code-checks.xml applies only to managed-agent-server, but nothing
enforced it outside the clean-verify lanes, which need MariaDB and a host
lock and have starved before. checkstyle:check declares no dependency
resolution, so it needs no sibling install and slots in beside the two
existing checkstyle steps.
64669 bytes, within the 4096-byte ratchet over the 69416 baseline.
---------
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
172 lines
7.4 KiB
Java
172 lines
7.4 KiB
Java
package db.migration;
|
|
|
|
import com.alibaba.qwen.code.managedagent.store.EventIdentity;
|
|
import com.alibaba.qwen.code.managedagent.store.EventIdentity.Identity;
|
|
import com.fasterxml.jackson.core.type.TypeReference;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import org.flywaydb.core.api.migration.BaseJavaMigration;
|
|
import org.flywaydb.core.api.migration.Context;
|
|
|
|
import java.sql.Connection;
|
|
import java.sql.PreparedStatement;
|
|
import java.sql.ResultSet;
|
|
import java.sql.SQLException;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* Gives events written before V14 the Item and Part identity that the server
|
|
* now assigns when it accepts an event. It applies the same
|
|
* {@link EventIdentity} rule, one Session at a time in sequence order, so that
|
|
* replayed events name the Items and Parts of the Snapshot.
|
|
*/
|
|
public class V15__managed_event_identity extends BaseJavaMigration {
|
|
private static final TypeReference<Map<String, Object>> MAP_TYPE =
|
|
new TypeReference<>() {
|
|
};
|
|
private static final int BATCH_SIZE = 500;
|
|
// Rows read per query, so memory does not grow with a Session's length.
|
|
private static final int PAGE_SIZE = 5000;
|
|
// Sessions listed per query, so memory does not grow with their number.
|
|
private static final int SESSION_PAGE_SIZE = 1000;
|
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
@Override
|
|
public void migrate(Context context) throws Exception {
|
|
Connection connection = context.getConnection();
|
|
try (PreparedStatement firstSessions = connection.prepareStatement(
|
|
"SELECT tenant_id, session_id FROM"
|
|
+ " managed_agent_session ORDER BY tenant_id,"
|
|
+ " session_id LIMIT ?");
|
|
PreparedStatement nextSessions = connection.prepareStatement(
|
|
"SELECT tenant_id, session_id FROM"
|
|
+ " managed_agent_session WHERE tenant_id > ?"
|
|
+ " OR (tenant_id = ? AND session_id > ?)"
|
|
+ " ORDER BY tenant_id, session_id LIMIT ?");
|
|
PreparedStatement select = connection.prepareStatement("SELECT"
|
|
+ " sequence_id, event_type, turn_id, CASE WHEN"
|
|
+ " event_type IN ('turn.accepted',"
|
|
+ " 'item.output_text.delta', 'item.reasoning.delta',"
|
|
+ " 'item.tool_call.updated') THEN data_json END AS"
|
|
+ " data_json FROM managed_agent_event WHERE"
|
|
+ " tenant_id = ? AND session_id = ? AND sequence_id"
|
|
+ " > ? ORDER BY sequence_id LIMIT ?");
|
|
PreparedStatement update = connection.prepareStatement(
|
|
"UPDATE managed_agent_event SET item_id = ?,"
|
|
+ " content_part_id = ? WHERE tenant_id = ?"
|
|
+ " AND session_id = ? AND sequence_id"
|
|
+ " BETWEEN ? AND ?")) {
|
|
firstSessions.setInt(1, SESSION_PAGE_SIZE);
|
|
nextSessions.setInt(4, SESSION_PAGE_SIZE);
|
|
List<String[]> sessions = sessions(firstSessions);
|
|
while (!sessions.isEmpty()) {
|
|
for (String[] session : sessions) {
|
|
backfill(select, update, session[0], session[1]);
|
|
}
|
|
if (sessions.size() < SESSION_PAGE_SIZE) {
|
|
break;
|
|
}
|
|
String[] last = sessions.getLast();
|
|
nextSessions.setString(1, last[0]);
|
|
nextSessions.setString(2, last[0]);
|
|
nextSessions.setString(3, last[1]);
|
|
sessions = sessions(nextSessions);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Sessions come from their own table, keyed by the primary key, so every
|
|
// page is an index range; a Session without events reads nothing.
|
|
private static List<String[]> sessions(PreparedStatement query)
|
|
throws SQLException {
|
|
List<String[]> sessions = new ArrayList<>();
|
|
try (ResultSet rows = query.executeQuery()) {
|
|
while (rows.next()) {
|
|
sessions.add(new String[] {rows.getString(1),
|
|
rows.getString(2)});
|
|
}
|
|
}
|
|
return sessions;
|
|
}
|
|
|
|
// A text stream shares one identity across consecutive rows, so each run
|
|
// of equal identities is one ranged update rather than one per row.
|
|
private void backfill(PreparedStatement select, PreparedStatement update,
|
|
String tenantId, String sessionId) throws Exception {
|
|
select.setString(1, tenantId);
|
|
select.setString(2, sessionId);
|
|
update.setString(3, tenantId);
|
|
update.setString(4, sessionId);
|
|
select.setInt(4, PAGE_SIZE);
|
|
int pending = 0;
|
|
Identity run = null;
|
|
long first = 0;
|
|
long last = 0;
|
|
Identity previous = null;
|
|
long previousSequence = -1;
|
|
int read;
|
|
do {
|
|
select.setLong(3, previousSequence < 0 ? 0 : previousSequence);
|
|
read = 0;
|
|
try (ResultSet rows = select.executeQuery()) {
|
|
while (rows.next()) {
|
|
read++;
|
|
long sequence = rows.getLong("sequence_id");
|
|
String data = rows.getString("data_json");
|
|
Identity identity = EventIdentity.of(
|
|
rows.getString("event_type"),
|
|
rows.getString("turn_id"), sequence,
|
|
data == null ? Map.of()
|
|
: objectMapper.readValue(data, MAP_TYPE),
|
|
previousSequence == sequence - 1 ? previous
|
|
: null);
|
|
previous = identity;
|
|
previousSequence = sequence;
|
|
if (identity.itemId() == null) {
|
|
continue;
|
|
}
|
|
if (run != null && sequence == last + 1
|
|
&& identity.itemId().equals(run.itemId())
|
|
&& Objects.equals(identity.contentPartId(),
|
|
run.contentPartId())) {
|
|
last = sequence;
|
|
continue;
|
|
}
|
|
if (run != null) {
|
|
pending = add(update, run, first, last, pending);
|
|
}
|
|
run = identity;
|
|
first = sequence;
|
|
last = sequence;
|
|
}
|
|
}
|
|
} while (read == PAGE_SIZE);
|
|
if (run != null) {
|
|
pending = add(update, run, first, last, pending);
|
|
}
|
|
if (pending > 0) {
|
|
execute(update);
|
|
}
|
|
}
|
|
|
|
private static int add(PreparedStatement update, Identity identity,
|
|
long first, long last, int pending) throws SQLException {
|
|
update.setString(1, identity.itemId());
|
|
update.setString(2, identity.contentPartId());
|
|
update.setLong(5, first);
|
|
update.setLong(6, last);
|
|
update.addBatch();
|
|
if (pending + 1 < BATCH_SIZE) {
|
|
return pending + 1;
|
|
}
|
|
execute(update);
|
|
return 0;
|
|
}
|
|
|
|
private static void execute(PreparedStatement update) throws SQLException {
|
|
update.executeBatch();
|
|
update.clearBatch();
|
|
}
|
|
}
|