forked from Mirrors/gomuks
hicli/init: send spaces in first payload
This commit is contained in:
parent
2ea80dac6f
commit
5483b077c7
5 changed files with 72 additions and 27 deletions
|
@ -27,6 +27,7 @@ const (
|
||||||
FROM room
|
FROM room
|
||||||
`
|
`
|
||||||
getRoomsBySortingTimestampQuery = getRoomBaseQuery + `WHERE sorting_timestamp < $1 AND sorting_timestamp > 0 ORDER BY sorting_timestamp DESC LIMIT $2`
|
getRoomsBySortingTimestampQuery = getRoomBaseQuery + `WHERE sorting_timestamp < $1 AND sorting_timestamp > 0 ORDER BY sorting_timestamp DESC LIMIT $2`
|
||||||
|
getRoomsByTypeQuery = getRoomBaseQuery + `WHERE room_type = $1`
|
||||||
getRoomByIDQuery = getRoomBaseQuery + `WHERE room_id = $1`
|
getRoomByIDQuery = getRoomBaseQuery + `WHERE room_id = $1`
|
||||||
ensureRoomExistsQuery = `
|
ensureRoomExistsQuery = `
|
||||||
INSERT INTO room (room_id) VALUES ($1)
|
INSERT INTO room (room_id) VALUES ($1)
|
||||||
|
@ -96,6 +97,10 @@ func (rq *RoomQuery) GetBySortTS(ctx context.Context, maxTS time.Time, limit int
|
||||||
return rq.QueryMany(ctx, getRoomsBySortingTimestampQuery, maxTS.UnixMilli(), limit)
|
return rq.QueryMany(ctx, getRoomsBySortingTimestampQuery, maxTS.UnixMilli(), limit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rq *RoomQuery) GetAllSpaces(ctx context.Context) ([]*Room, error) {
|
||||||
|
return rq.QueryMany(ctx, getRoomsByTypeQuery, event.RoomTypeSpace)
|
||||||
|
}
|
||||||
|
|
||||||
func (rq *RoomQuery) Upsert(ctx context.Context, room *Room) error {
|
func (rq *RoomQuery) Upsert(ctx context.Context, room *Room) error {
|
||||||
return rq.Exec(ctx, upsertRoomFromSyncQuery, room.sqlVariables()...)
|
return rq.Exec(ctx, upsertRoomFromSyncQuery, room.sqlVariables()...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,13 +26,18 @@ const (
|
||||||
getTopLevelSpaces = `
|
getTopLevelSpaces = `
|
||||||
SELECT space_id
|
SELECT space_id
|
||||||
FROM (SELECT DISTINCT(space_id) FROM space_edge) outeredge
|
FROM (SELECT DISTINCT(space_id) FROM space_edge) outeredge
|
||||||
|
LEFT JOIN room_account_data ON
|
||||||
|
room_account_data.user_id = $1
|
||||||
|
AND room_account_data.room_id = outeredge.space_id
|
||||||
|
AND room_account_data.type = 'org.matrix.msc3230.space_order'
|
||||||
WHERE NOT EXISTS(
|
WHERE NOT EXISTS(
|
||||||
SELECT 1
|
SELECT 1
|
||||||
FROM space_edge inneredge
|
FROM space_edge inneredge
|
||||||
INNER JOIN room ON inneredge.space_id = room.room_id
|
INNER JOIN room ON inneredge.space_id = room.room_id
|
||||||
WHERE inneredge.child_id = outeredge.space_id
|
WHERE inneredge.child_id = outeredge.space_id
|
||||||
AND (inneredge.child_event_rowid IS NOT NULL OR inneredge.parent_validated)
|
AND (inneredge.child_event_rowid IS NOT NULL OR inneredge.parent_validated)
|
||||||
)
|
) AND EXISTS(SELECT 1 FROM room WHERE room_id = space_id AND room_type = 'm.space')
|
||||||
|
ORDER BY room_account_data.content->>'$.order' NULLS LAST, space_id
|
||||||
`
|
`
|
||||||
revalidateAllParents = `
|
revalidateAllParents = `
|
||||||
UPDATE space_edge
|
UPDATE space_edge
|
||||||
|
@ -196,6 +201,12 @@ func (seq *SpaceEdgeQuery) GetAll(ctx context.Context, spaceID id.RoomID) (map[i
|
||||||
return edges, err
|
return edges, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var roomIDScanner = dbutil.ConvertRowFn[id.RoomID](dbutil.ScanSingleColumn[id.RoomID])
|
||||||
|
|
||||||
|
func (seq *SpaceEdgeQuery) GetTopLevelIDs(ctx context.Context, userID id.UserID) ([]id.RoomID, error) {
|
||||||
|
return roomIDScanner.NewRowIter(seq.GetDB().Query(ctx, getTopLevelSpaces, userID)).AsList()
|
||||||
|
}
|
||||||
|
|
||||||
type SpaceEdge struct {
|
type SpaceEdge struct {
|
||||||
SpaceID id.RoomID `json:"space_id,omitempty"`
|
SpaceID id.RoomID `json:"space_id,omitempty"`
|
||||||
ChildID id.RoomID `json:"child_id"`
|
ChildID id.RoomID `json:"child_id"`
|
||||||
|
|
|
@ -38,6 +38,7 @@ type SyncComplete struct {
|
||||||
LeftRooms []id.RoomID `json:"left_rooms"`
|
LeftRooms []id.RoomID `json:"left_rooms"`
|
||||||
InvitedRooms []*database.InvitedRoom `json:"invited_rooms"`
|
InvitedRooms []*database.InvitedRoom `json:"invited_rooms"`
|
||||||
SpaceEdges map[id.RoomID][]*database.SpaceEdge `json:"space_edges"`
|
SpaceEdges map[id.RoomID][]*database.SpaceEdge `json:"space_edges"`
|
||||||
|
TopLevelSpaces []id.RoomID `json:"top_level_spaces"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *SyncComplete) IsEmpty() bool {
|
func (c *SyncComplete) IsEmpty() bool {
|
||||||
|
|
|
@ -66,6 +66,49 @@ func (h *HiClient) getInitialSyncRoom(ctx context.Context, room *database.Room)
|
||||||
func (h *HiClient) GetInitialSync(ctx context.Context, batchSize int) iter.Seq[*SyncComplete] {
|
func (h *HiClient) GetInitialSync(ctx context.Context, batchSize int) iter.Seq[*SyncComplete] {
|
||||||
return func(yield func(*SyncComplete) bool) {
|
return func(yield func(*SyncComplete) bool) {
|
||||||
maxTS := time.Now().Add(1 * time.Hour)
|
maxTS := time.Now().Add(1 * time.Hour)
|
||||||
|
{
|
||||||
|
spaces, err := h.DB.Room.GetAllSpaces(ctx)
|
||||||
|
if err != nil {
|
||||||
|
if ctx.Err() == nil {
|
||||||
|
zerolog.Ctx(ctx).Err(err).Msg("Failed to get initial spaces to send to client")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
payload := SyncComplete{
|
||||||
|
Rooms: make(map[id.RoomID]*SyncRoom, len(spaces)),
|
||||||
|
}
|
||||||
|
for _, room := range spaces {
|
||||||
|
payload.Rooms[room.ID] = h.getInitialSyncRoom(ctx, room)
|
||||||
|
if ctx.Err() != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
payload.TopLevelSpaces, err = h.DB.SpaceEdge.GetTopLevelIDs(ctx, h.Account.UserID)
|
||||||
|
if err != nil {
|
||||||
|
if ctx.Err() == nil {
|
||||||
|
zerolog.Ctx(ctx).Err(err).Msg("Failed to get top-level space IDs to send to client")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
payload.SpaceEdges, err = h.DB.SpaceEdge.GetAll(ctx, "")
|
||||||
|
if err != nil {
|
||||||
|
if ctx.Err() == nil {
|
||||||
|
zerolog.Ctx(ctx).Err(err).Msg("Failed to get space edges to send to client")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
payload.InvitedRooms, err = h.DB.InvitedRoom.GetAll(ctx)
|
||||||
|
if err != nil {
|
||||||
|
if ctx.Err() == nil {
|
||||||
|
zerolog.Ctx(ctx).Err(err).Msg("Failed to get invited rooms to send to client")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
payload.ClearState = true
|
||||||
|
if !yield(&payload) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
for i := 0; ; i++ {
|
for i := 0; ; i++ {
|
||||||
rooms, err := h.DB.Room.GetBySortTS(ctx, maxTS, batchSize)
|
rooms, err := h.DB.Room.GetBySortTS(ctx, maxTS, batchSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -77,24 +120,6 @@ func (h *HiClient) GetInitialSync(ctx context.Context, batchSize int) iter.Seq[*
|
||||||
payload := SyncComplete{
|
payload := SyncComplete{
|
||||||
Rooms: make(map[id.RoomID]*SyncRoom, len(rooms)),
|
Rooms: make(map[id.RoomID]*SyncRoom, len(rooms)),
|
||||||
}
|
}
|
||||||
if i == 0 {
|
|
||||||
payload.InvitedRooms, err = h.DB.InvitedRoom.GetAll(ctx)
|
|
||||||
if err != nil {
|
|
||||||
if ctx.Err() == nil {
|
|
||||||
zerolog.Ctx(ctx).Err(err).Msg("Failed to get invited rooms to send to client")
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// TODO include space rooms in first batch too?
|
|
||||||
payload.SpaceEdges, err = h.DB.SpaceEdge.GetAll(ctx, "")
|
|
||||||
if err != nil {
|
|
||||||
if ctx.Err() == nil {
|
|
||||||
zerolog.Ctx(ctx).Err(err).Msg("Failed to get space edges to send to client")
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
payload.ClearState = true
|
|
||||||
}
|
|
||||||
for _, room := range rooms {
|
for _, room := range rooms {
|
||||||
if room.SortingTimestamp == rooms[len(rooms)-1].SortingTimestamp {
|
if room.SortingTimestamp == rooms[len(rooms)-1].SortingTimestamp {
|
||||||
break
|
break
|
||||||
|
@ -105,7 +130,9 @@ func (h *HiClient) GetInitialSync(ctx context.Context, batchSize int) iter.Seq[*
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !yield(&payload) || len(rooms) < batchSize {
|
if !yield(&payload) {
|
||||||
|
return
|
||||||
|
} else if len(rooms) < batchSize {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,7 @@ export interface SyncCompleteData {
|
||||||
left_rooms: RoomID[] | null
|
left_rooms: RoomID[] | null
|
||||||
account_data: Record<EventType, DBAccountData> | null
|
account_data: Record<EventType, DBAccountData> | null
|
||||||
space_edges: Record<RoomID, Omit<DBSpaceEdge, "space_id">[]> | null
|
space_edges: Record<RoomID, Omit<DBSpaceEdge, "space_id">[]> | null
|
||||||
|
top_level_spaces: RoomID[] | null
|
||||||
since?: string
|
since?: string
|
||||||
clear_state?: boolean
|
clear_state?: boolean
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue