Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@juzi/wechaty",
"version": "1.0.160",
"version": "1.0.161",
"description": "Wechaty is a RPA SDK for Chatbot Makers.",
"type": "module",
"exports": {
Expand Down
144 changes: 0 additions & 144 deletions src/wechaty-mixins/puppet-mixin-dirty-pool.spec.ts

This file was deleted.

55 changes: 19 additions & 36 deletions src/wechaty-mixins/puppet-mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ import type {
CallImpl,
ContactImpl,
ContactInterface,
MessageImpl,
RoomImpl,
TagGroupInterface,
TagInterface,
WxxdOrderImpl,
WxxdProductImpl,
} from '../user-modules/mod.js'

import type {
Expand Down Expand Up @@ -724,46 +728,26 @@ const puppetMixin = <MixinBase extends WechatifyUserModuleMixin & GErrorMixin &
case 'dirty':
/**
* https://github.com/wechaty/wechaty-puppet-service/issues/43
*
* `dirty` semantics: the puppet-service told us the cached payload
* for this id is stale. It is NOT a request to load the payload.
*
* The old handler used `this.Xxx.find({ id })` which, on pool miss,
* constructs a fresh user-layer instance AND calls `.ready()` — a
* puppet-side gRPC round-trip. For a `dirty` event about an id
* that no business code has ever touched, this turned a passive
* "invalidate if cached" signal into an active fetch, amplifying
* dirty-event bursts (e.g. during message storms) into extra
* puppet-service QPS.
*
* Fix: for pooled user-modules, look the instance up in the pool
* directly and only call `.ready(true)` when it is already there.
* The Call branch (below) already follows this shape via
* `__callPool.get(...)`. Message has no pool, so its branch is a
* no-op break (any caller wanting a Message must load it itself).
*/
puppet.on('dirty', async ({ payloadType, payloadId }) => {
try {
switch (payloadType) {
case PUPPET.types.Payload.Contact: {
const cached = this.Contact.pool.get(payloadId)
if (cached) await cached.ready(true)
const contact = await this.Contact.find({ id: payloadId }) as unknown as undefined | ContactImpl
await contact?.ready(true)
break
}
case PUPPET.types.Payload.Room: {
const cached = this.Room.pool.get(payloadId)
if (cached) await cached.ready(true)
const room = await this.Room.find({ id: payloadId }) as unknown as undefined | RoomImpl
await room?.ready(true)
break
}
case PUPPET.types.Payload.RoomMember: {
if (payloadId.includes(PUPPET.STRING_SPLITTER)) {
break
}
// A bare (non-composite) RoomMember dirty id addresses the
// whole room, mirroring the Room branch — but never load
// a new Room here.
const cached = this.Room.pool.get(payloadId)
if (cached) await cached.ready()
const room = await this.Room.find({ id: payloadId }) as unknown as undefined | RoomImpl
await room?.ready()
break
}

Expand All @@ -773,27 +757,26 @@ const puppetMixin = <MixinBase extends WechatifyUserModuleMixin & GErrorMixin &
case PUPPET.types.Payload.Friendship:
// Friendship has no payload
break
case PUPPET.types.Payload.Message:
// Message has no user-layer pool (see message.ts: `load`
// constructs a fresh instance every call). Dirty for a
// Message id is therefore a no-op at this layer — the
// cache-mixin listener still invalidates the puppet-side
// payload cache alongside this handler.
case PUPPET.types.Payload.Message: {
// Message does not need to dirty (?)
const message = await this.Message.find({ id: payloadId }) as unknown as undefined | MessageImpl
await message?.ready(true)
break
}
case PUPPET.types.Payload.Tag:
break
case PUPPET.types.Payload.TagGroup:
break
case PUPPET.types.Payload.Post:
break
case PUPPET.types.Payload.WxxdProduct: {
const cached = this.WxxdProduct.pool.get(payloadId)
if (cached) await cached.ready(true)
const product = await this.WxxdProduct.find({ id: payloadId }) as unknown as undefined | WxxdProductImpl
await product?.ready(true)
break
}
case PUPPET.types.Payload.WxxdOrder: {
const cached = this.WxxdOrder.pool.get(payloadId)
if (cached) await cached.ready(true)
const order = await this.WxxdOrder.find({ id: payloadId }) as unknown as undefined | WxxdOrderImpl
await order?.ready(true)
break
}
case PUPPET.types.Payload.Call: {
Expand Down
Loading