perf(lastleg): reuse warehouse directory within sync generation
This commit is contained in:
+16
-6
@@ -68,12 +68,22 @@ public class AppointmentWorkFactAdapter implements AppointmentWorkFactGateway {
|
||||
});
|
||||
return result;
|
||||
}
|
||||
public List<Requirement> requirements(ContainerSource source,Flow effectiveFlow) {
|
||||
var provider=requirements.getIfAvailable();
|
||||
if(provider==null) throw unavailable("原预约需求与批次清单适配尚未接入,不能生成不完整工作清单");
|
||||
var result=provider.requirements(source,effectiveFlow);
|
||||
if(result==null || result.isEmpty()) throw unavailable("原预约需求清单缺失,不能以空清单完成路线生成");
|
||||
return List.copyOf(result);
|
||||
/** 每次生成建立独立读取器;没有实际需求读取时不引入原业务依赖。 */
|
||||
public RequirementReader openRequirements() {
|
||||
return new RequirementReader() {
|
||||
private RequirementReader reader;
|
||||
/** 首次实际读取才取得原域作用域,保留每份需求的完整性校验。 */
|
||||
public List<Requirement> read(ContainerSource source,Flow effectiveFlow) {
|
||||
if(reader==null) {
|
||||
var provider=requirements.getIfAvailable();
|
||||
if(provider==null) throw unavailable("原预约需求与批次清单适配尚未接入,不能生成不完整工作清单");
|
||||
reader=provider.openRequirements();
|
||||
}
|
||||
var result=reader.read(source,effectiveFlow);
|
||||
if(result==null || result.isEmpty()) throw unavailable("原预约需求清单缺失,不能以空清单完成路线生成");
|
||||
return List.copyOf(result);
|
||||
}
|
||||
};
|
||||
}
|
||||
static void append(Map<String,Fact> target,List<FactRequest> requests,List<Fact> facts) {
|
||||
if(facts==null || facts.size()!=requests.size()) throw unavailable("工作事实响应不完整");
|
||||
|
||||
+5
-3
@@ -27,8 +27,8 @@ public interface AppointmentWorkFactGateway {
|
||||
}
|
||||
SourcePage discover(String after, int size);
|
||||
ContainerSource container(String containerBookingId);
|
||||
/** Original appointment core supplies the complete current obligation/batch manifest, including explicit replacement keys. */
|
||||
List<Requirement> requirements(ContainerSource source,Flow effectiveFlow);
|
||||
/** 建立本次原预约需求读取作用域,保持完整批次及明确替代关系。 */
|
||||
RequirementReader openRequirements();
|
||||
Map<String, Fact> facts(List<AppointmentWorkState> states);
|
||||
Owner owner(String id, Actor actor);
|
||||
Responsibility supplier(String id);
|
||||
@@ -41,5 +41,7 @@ public interface AppointmentWorkFactGateway {
|
||||
/** IAM-backed active platform operators; display names supplied by callers are never trusted. */
|
||||
interface OwnerDirectory { Owner activePlatformOwner(String id); }
|
||||
interface SupplierDirectory { Responsibility activeSupplier(String id); }
|
||||
interface RequirementProvider { List<Requirement> requirements(ContainerSource source,Flow effectiveFlow); }
|
||||
/** 单次生成显式复用目录,不跨请求保存来源事实。 */
|
||||
interface RequirementReader { List<Requirement> read(ContainerSource source,Flow effectiveFlow); }
|
||||
interface RequirementProvider { RequirementReader openRequirements(); }
|
||||
}
|
||||
|
||||
+7
-6
@@ -36,6 +36,7 @@ public class AppointmentWorkSyncService {
|
||||
timing.next(SyncPhase.GENERATE);
|
||||
// 保留全部历史与稳定键顺序;逐柜更新立即进入本次工作集,不跨事务缓存。
|
||||
var known=workingSet();
|
||||
var requirementReader=gateway.openRequirements();
|
||||
int created=0; var ids=new HashSet<String>();
|
||||
for(var source:page.containers()) {
|
||||
validateSource(source);
|
||||
@@ -45,13 +46,13 @@ public class AppointmentWorkSyncService {
|
||||
if(existing.isEmpty()) {
|
||||
if(source.establishedFlow()==Flow.UNKNOWN) {
|
||||
var route=create(source,Type.ROUTE,null,Flow.UNKNOWN); route.setFollowupDate(LocalDate.now(route.getTimezone()==null?REMINDER_ZONE:zone(route.getTimezone()))); store.insert(route); known.put(route.getWorkItemKey(),route); created++;
|
||||
} else created+=generate(source,source.establishedFlow(),existing,SYSTEM,known).size();
|
||||
} else created+=generate(source,source.establishedFlow(),existing,SYSTEM,known,requirementReader).size();
|
||||
} else {
|
||||
var activeFlow=existing.stream().filter(s->s.getType()!=Type.ROUTE && !s.isRetired()).map(AppointmentWorkState::getFlow).findFirst().orElse(null);
|
||||
if(activeFlow!=null) created+=generate(source,activeFlow,existing,SYSTEM,known).size();
|
||||
if(activeFlow!=null) created+=generate(source,activeFlow,existing,SYSTEM,known,requirementReader).size();
|
||||
else for(var route:existing) if(route.getType()==Type.ROUTE && !route.isRetired()) {
|
||||
if(source.establishedFlow()!=Flow.UNKNOWN) {
|
||||
var generated=generate(source,source.establishedFlow(),existing,SYSTEM,known); created+=generated.size();
|
||||
var generated=generate(source,source.establishedFlow(),existing,SYSTEM,known,requirementReader); created+=generated.size();
|
||||
route.setFlow(source.establishedFlow()); route.setRetired(true); route.setRetirementReason("ROUTE_CONFIRMED"); route.setReplacementKeys(generated); store.save(route);
|
||||
} else if(!Objects.equals(route.getSourceVersion(),source.sourceVersion())) {
|
||||
route.setSourceVersion(source.sourceVersion()); route.setContainerNo(source.containerNo()); route.setTimezone(source.timezone()); store.save(route);
|
||||
@@ -125,7 +126,7 @@ public class AppointmentWorkSyncService {
|
||||
}
|
||||
/** 命令入口仍在调用方守卫事务中即时加载工作集。 */
|
||||
List<String> generate(ContainerSource source,Flow flow,List<AppointmentWorkState> existing,Actor actor) {
|
||||
return generate(source,flow,existing,actor,workingSet());
|
||||
return generate(source,flow,existing,actor,workingSet(),gateway.openRequirements());
|
||||
}
|
||||
/** 与持久层全量读取保持稳定键顺序,并保留退役事项及原读取上限。 */
|
||||
private Map<String,AppointmentWorkState> workingSet() {
|
||||
@@ -135,10 +136,10 @@ public class AppointmentWorkSyncService {
|
||||
}
|
||||
/** 同页各柜共享最新状态,新增、跨柜关联和退役仍逐项持久化。 */
|
||||
private List<String> generate(ContainerSource source,Flow flow,List<AppointmentWorkState> existing,Actor actor,
|
||||
Map<String,AppointmentWorkState> known) {
|
||||
Map<String,AppointmentWorkState> known,RequirementReader requirementReader) {
|
||||
validateSource(source);
|
||||
if(flow==Flow.UNKNOWN) throw conflict("真实送货路线尚未明确");
|
||||
var requirements=gateway.requirements(source,flow);
|
||||
var requirements=requirementReader.read(source,flow);
|
||||
source=new ContainerSource(source.containerBookingId(),source.containerNo(),source.departedAt(),source.departedLocalAt(),source.sailedEvidenceLocalAt(),source.sourceVersion(),source.establishedFlow(),source.timezone(),requirements);
|
||||
validateSource(source);
|
||||
if(requirements.isEmpty()) throw conflict("真实送货需求尚未明确,不能生成空清单");
|
||||
|
||||
Reference in New Issue
Block a user