Skip to content

Commit

Permalink
Try to poll for webhook changes
Browse files Browse the repository at this point in the history
  • Loading branch information
jveski committed Dec 15, 2023
1 parent 193a723 commit 0490de4
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 3 deletions.
20 changes: 20 additions & 0 deletions keycloak/keycloak.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,26 @@ func (k *Keycloak) GetUser(ctx context.Context, userID string) (*User, error) {
return k.buildUser(ctx, kcuser)
}

// GetUserAtETag returns the user object at the given etag, or a possibly different version on timeout.
//
// This is useful when avoiding backtracking for cases in which a change has been written to Stripe but
// the corresponding webhook may not have been handled.
func (k *Keycloak) GetUserAtETag(ctx context.Context, userID string, etag int64) (user *User, err error) {
for i := 0; i < 15; i++ {
user, err = k.GetUser(ctx, userID)
if err != nil {
return nil, err
}
if etag == 0 || user.StripeETag >= etag {
return user, nil
}

time.Sleep(time.Millisecond * 100) // backoff + jitter would be nice here
}
log.Printf("timeout while waiting for Stripe webhook")
return user, nil // timeout
}

func (k *Keycloak) GetUserByEmail(ctx context.Context, email string) (*User, error) {
token, err := k.GetToken(ctx)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,14 @@ func newRegistrationFormHandler(kc *keycloak.Keycloak) http.HandlerFunc {

func newProfileViewHandler(kc *keycloak.Keycloak, pc *stripeutil.PriceCache) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
user, err := kc.GetUser(r.Context(), getUserID(r))
etagString := r.URL.Query().Get("i")
etag, _ := strconv.ParseInt(etagString, 10, 0)
user, err := kc.GetUserAtETag(r.Context(), getUserID(r), etag)
if err != nil {
renderSystemError(w, "error while fetching user: %s", err)
return
}

etagString := r.URL.Query().Get("i")
etag, _ := strconv.ParseInt(etagString, 10, 0)
viewData := map[string]any{
"page": "profile",
"user": user,
Expand Down

0 comments on commit 0490de4

Please sign in to comment.