diff --git a/loadtest/im-pressure/httpapi.go b/loadtest/im-pressure/httpapi.go index e61c513..4a23830 100644 --- a/loadtest/im-pressure/httpapi.go +++ b/loadtest/im-pressure/httpapi.go @@ -197,15 +197,17 @@ func (a *apiClient) findPendingFriendRequest(ctx context.Context, target Account func (a *apiClient) createFriendRequest(ctx context.Context, source, target AccountRecord) (*friendRequestResponse, error) { var result friendRequestResponse body := map[string]any{"target_user_id": target.UserID, "message": "loadtest", "source": "search", "source_topic": ""} + idempotencyKey := fmt.Sprintf("loadtest-friend-%d-%s-%04d", time.Now().UnixNano(), source.Machine, source.Index) err := a.do(ctx, http.MethodPost, "/v1/im/friend-requests", source.Token, - fmt.Sprintf("loadtest-friend-%04d", source.Index), body, &result) + idempotencyKey, body, &result) return &result, err } func (a *apiClient) acceptFriendRequest(ctx context.Context, target AccountRecord, requestID string) (*friendRequestResponse, error) { var result friendRequestResponse + idempotencyKey := fmt.Sprintf("loadtest-friend-accept-%d", time.Now().UnixNano()) err := a.do(ctx, http.MethodPost, "/v1/im/friend-requests/"+url.PathEscape(requestID)+"/accept", target.Token, - "loadtest-friend-accept-"+requestID, map[string]any{}, &result) + idempotencyKey, map[string]any{}, &result) return &result, err } diff --git a/loadtest/im-pressure/prepare.go b/loadtest/im-pressure/prepare.go index acc5d4a..a84f994 100644 --- a/loadtest/im-pressure/prepare.go +++ b/loadtest/im-pressure/prepare.go @@ -127,12 +127,23 @@ func prepareFriendships(ctx context.Context, cfg *Config, manifest *Manifest, ap err := parallelAccounts(ctx, pairs, cfg.PrepareWorkers, func(a AccountRecord) error { return retryPrepareOperation(ctx, fmt.Sprintf("friend-pair-%04d", a.Index), func() error { b := *accounts[accountKey("b", a.Index)] - if a.P2PTopic != "" && b.P2PTopic == a.P2PTopic { - return nil - } if a.UserID == "" || b.UserID == "" { return fmt.Errorf("pair %d has missing user ID", a.Index) } + conversation, conversationErr := api.ensureP2P(ctx, a, b) + if conversationErr == nil && conversation.Relationship == "friend" && conversation.Topic != "" { + mu.Lock() + accounts[accountKey("a", a.Index)].P2PTopic = conversation.Topic + accounts[accountKey("b", a.Index)].P2PTopic = conversation.Topic + mu.Unlock() + return nil + } + if conversationErr != nil { + var apiErr *apiError + if !errors.As(conversationErr, &apiErr) || apiErr.Status != http.StatusForbidden { + return fmt.Errorf("check friend pair %d: %w", a.Index, conversationErr) + } + } request, requestErr := api.createFriendRequest(ctx, a, b) if requestErr == nil && request.Status == "pending" { if _, requestErr = api.acceptFriendRequest(ctx, b, request.RequestID); requestErr != nil {