Skip to content
Open
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
5 changes: 5 additions & 0 deletions group.go
Original file line number Diff line number Diff line change
Expand Up @@ -653,12 +653,17 @@ func (cli *Client) getCachedGroupData(ctx context.Context, jid types.JID) (*grou
cli.groupCacheLock.Lock()
defer cli.groupCacheLock.Unlock()
if val, ok := cli.groupCache[jid]; ok {
cli.Log.Debugf("Group participants cache HIT for group %s (has %d members)", jid, len(val.Members))
return val, nil
}
cli.Log.Debugf("Group participants cache MISS for group %s, fetching from server", jid)
_, err := cli.getGroupInfo(ctx, jid, false)
if err != nil {
return nil, err
}
if cachedData := cli.groupCache[jid]; cachedData != nil {
cli.Log.Debugf("Group participants cache populated for %s with %d members", jid, len(cachedData.Members))
}
return cli.groupCache[jid], nil
}

Expand Down
4 changes: 4 additions & 0 deletions store/noop.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,10 @@ func (n *NoopStore) GetManyLIDsForPNs(ctx context.Context, pns []types.JID) (map
return nil, n.Error
}

func (n *NoopStore) GetManyPNsForLIDs(ctx context.Context, lids []types.JID) (map[types.JID]types.JID, error) {
return nil, n.Error
}

func (n *NoopStore) GetPNForLID(ctx context.Context, lid types.JID) (types.JID, error) {
return types.JID{}, n.Error
}
Expand Down
63 changes: 63 additions & 0 deletions store/sqlstore/lidmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,69 @@ func (s *CachedLIDMap) GetManyLIDsForPNs(ctx context.Context, pns []types.JID) (
return result, err
}

func (s *CachedLIDMap) GetManyPNsForLIDs(ctx context.Context, lids []types.JID) (map[types.JID]types.JID, error) {
if len(lids) == 0 {
return nil, nil
}

result := make(map[types.JID]types.JID, len(lids))

s.lidCacheLock.RLock()
missingLIDs := make([]string, 0, len(lids))
missingLIDDevices := make(map[string][]types.JID)
for _, lid := range lids {
if lid.Server != types.HiddenUserServer {
continue
}
if pnUser, ok := s.lidToPNCache[lid.User]; ok && pnUser != "" {
result[lid] = types.JID{User: pnUser, Device: lid.Device, Server: types.DefaultUserServer}
} else if !s.cacheFilled {
missingLIDs = append(missingLIDs, lid.User)
missingLIDDevices[lid.User] = append(missingLIDDevices[lid.User], lid)
}
}
s.lidCacheLock.RUnlock()

if len(missingLIDs) == 0 {
return result, nil
}

s.lidCacheLock.Lock()
defer s.lidCacheLock.Unlock()

var rows dbutil.Rows
var err error
if s.db.Dialect == dbutil.Postgres && PostgresArrayWrapper != nil {
rows, err = s.db.Query(
ctx,
`SELECT lid, pn FROM whatsmeow_lid_map WHERE lid = ANY($1)`,
PostgresArrayWrapper(missingLIDs),
)
} else {
placeholders := make([]string, len(missingLIDs))
for i := range missingLIDs {
placeholders[i] = fmt.Sprintf("$%d", i+1)
}
rows, err = s.db.Query(
ctx,
fmt.Sprintf(`SELECT lid, pn FROM whatsmeow_lid_map WHERE lid IN (%s)`, strings.Join(placeholders, ",")),
exslices.CastToAny(missingLIDs)...,
)
}
if err != nil {
return nil, err
}
err = s.scanManyLids(rows, func(lid, pn string) {
for _, dev := range missingLIDDevices[lid] {
pnDev := dev
pnDev.Server = types.DefaultUserServer
pnDev.User = pn
result[dev] = pnDev.ToNonAD()
}
})
return result, err
}

func (s *CachedLIDMap) PutLIDMapping(ctx context.Context, lid, pn types.JID) error {
if lid.Server != types.HiddenUserServer || pn.Server != types.DefaultUserServer {
return fmt.Errorf("invalid PutLIDMapping call %s/%s", lid, pn)
Expand Down
1 change: 1 addition & 0 deletions store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ type LIDStore interface {
GetPNForLID(ctx context.Context, lid types.JID) (types.JID, error)
GetLIDForPN(ctx context.Context, pn types.JID) (types.JID, error)
GetManyLIDsForPNs(ctx context.Context, pns []types.JID) (map[types.JID]types.JID, error)
GetManyPNsForLIDs(ctx context.Context, lids []types.JID) (map[types.JID]types.JID, error)
}

type AllSessionSpecificStores interface {
Expand Down
11 changes: 11 additions & 0 deletions user.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,19 +455,30 @@ func (cli *Client) GetUserDevicesContext(ctx context.Context, jids []types.JID)
defer cli.userDevicesCacheLock.Unlock()

var devices, jidsToSync, fbJIDsToSync []types.JID
var cacheHits, cacheMisses []types.JID
for _, jid := range jids {
cached, ok := cli.userDevicesCache[jid]
if ok && len(cached.devices) > 0 {
devices = append(devices, cached.devices...)
cacheHits = append(cacheHits, jid)
} else if jid.Server == types.MessengerServer {
fbJIDsToSync = append(fbJIDsToSync, jid)
cacheMisses = append(cacheMisses, jid)
} else if jid.IsBot() {
// Bot JIDs do not have devices, the usync query is empty
devices = append(devices, jid)
} else {
jidsToSync = append(jidsToSync, jid)
cacheMisses = append(cacheMisses, jid)
}
}

if len(cacheHits) > 0 {
cli.Log.Debugf("User devices cache HIT for %d JIDs: %v", len(cacheHits), cacheHits)
}
if len(cacheMisses) > 0 {
cli.Log.Debugf("User devices cache MISS for %d JIDs: %v", len(cacheMisses), cacheMisses)
}
if len(jidsToSync) > 0 {
list, err := cli.usync(ctx, jidsToSync, "query", "message", []waBinary.Node{
{Tag: "devices", Attrs: waBinary.Attrs{"version": "2"}},
Expand Down