Skip to content

Review: OpenPets × Everywhere bridge architecture + core event routing algorithm #3

Description

@kanade-EdTech

Architecture Review

整体设计是合理的,核心优点:

  1. 分层清晰:宿主层 / 适配层 / 事件契约 / 业务扩展四层结构合理,符合插件系统最佳实践。
  2. 低耦合策略正确:通过 event-contracts 解耦 OpenPets 与 Workday Everywhere SDK,避免 vendor lock-in。
  3. 本地优先符合 OpenPets 定位:所有 IPC 通过本地 socket/MCP,避免云依赖。
  4. 许可证隔离合理:MIT + Apache-2.0 分层,降低污染风险。

主要风险补充

  1. 事件爆炸问题:Everywhere 插件事件可能高频触发,需要 event batching。
  2. 双向链路循环风险:OpenPets → Everywhere → OpenPets 需要防止 feedback loop。
  3. 契约版本漂移:event-contracts 需要强 schema versioning + backward compatibility test。

核心算法:事件桥接与调度引擎

1. 事件模型

interface BaseEvent {
  id: string;
  type: string;
  timestamp: number;
  source: 'everywhere' | 'openpets';
  version: string;
  payload: any;
}

2. 核心算法:Event Router + Guard + Adapter

class EventBridge {
  private queue: BaseEvent[] = [];
  private processing = false;
  private lastEventMap = new Map<string, number>();

  push(event: BaseEvent) {
    if (!this.guard(event)) return;
    this.queue.push(event);
    this.flush();
  }

  private guard(event: BaseEvent): boolean {
    // 1. 去重(1000ms窗口)
    const last = this.lastEventMap.get(event.type);
    if (last && Date.now() - last < 1000) return false;
    this.lastEventMap.set(event.type, Date.now());

    // 2. 防循环事件
    if (event.payload?.fromBridge) return false;

    // 3. 白名单过滤
    const allowed = ['TaskStarted','TaskSucceeded','TaskFailed','TaskWaitingApproval','UserClickedPet'];
    if (!allowed.includes(event.type)) return false;

    return true;
  }

  private async flush() {
    if (this.processing) return;
    this.processing = true;

    while (this.queue.length > 0) {
      const event = this.queue.shift()!;

      const mapped = this.mapEvent(event);
      await this.dispatch(mapped);
    }

    this.processing = false;
  }

  private mapEvent(event: BaseEvent) {
    return {
      ...event,
      payload: this.transform(event)
    };
  }

  private transform(event: BaseEvent) {
    switch (event.type) {
      case 'TaskStarted':
        return { mood: 'working', bubble: 'Starting task...' };
      case 'TaskSucceeded':
        return { mood: 'happy', bubble: 'Done!' };
      case 'TaskFailed':
        return { mood: 'sad', bubble: 'Failed :(' };
      case 'TaskWaitingApproval':
        return { mood: 'thinking', bubble: 'Waiting approval' };
      default:
        return { mood: 'idle', bubble: '' };
    }
  }

  private async dispatch(event: BaseEvent) {
    if (event.source === 'everywhere') {
      await this.sendToOpenPets(event);
    } else {
      await this.sendToEverywhere(event);
    }
  }

  private async sendToOpenPets(event: BaseEvent) {
    // MCP / socket
    // openpets_react + openpets_say
    console.log('dispatch to OpenPets', event);
  }

  private async sendToEverywhere(event: BaseEvent) {
    console.log('dispatch to Everywhere', event);
  }
}

3. 核心调度策略补充(建议增强)

3.1 优先级队列(建议升级)

  • FAILED > WAITING_APPROVAL > STARTED > SUCCESS

3.2 批处理优化

flush interval: 100–300ms batch window

3.3 防抖策略

  • UI类事件 debounce 500ms
  • 状态类事件 throttle 1000ms

结论

架构是可落地的,核心关键在于:

  • event-contract 稳定性
  • loop guard
  • batch dispatch

建议下一步直接进入 M1 最小闭环实现(单向 Everywhere → OpenPets)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions