Skip to content

Commit

Permalink
Attempt fast user and storage count on partitioned tables in console …
Browse files Browse the repository at this point in the history
…API.
  • Loading branch information
zyro committed Jul 1, 2019
1 parent ce963ea commit fdc4d3c
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ The format is based on [keep a changelog](http://keepachangelog.com) and this pr
- Reset list of friend IDs in Facebook import when retrying the operation.
- Reset notifications in friend add when retrying the operation.
- Do not return storage list cursor unless there are further objects.
- Attempt fast user and storage count on partitioned tables in console API.

## [2.5.1] - 2019-05-03
### Changed
Expand Down
20 changes: 17 additions & 3 deletions server/console_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,19 +215,33 @@ func (s *ConsoleServer) WriteStorageObject(ctx context.Context, in *console.Writ

func countStorage(ctx context.Context, logger *zap.Logger, db *sql.DB) int32 {
var count sql.NullInt64
// First try a fast count on table metadata.
if err := db.QueryRowContext(ctx, "SELECT reltuples::BIGINT FROM pg_class WHERE relname = 'storage'").Scan(&count); err != nil {
logger.Warn("Error counting storage objects.", zap.Error(err))
if err == context.Canceled {
// If the context was cancelled do not attempt the full count.
// If the context was cancelled do not attempt any further counts.
return 0
}
}
if count.Valid && count.Int64 != 0 {
// Use fast count result.
// Use this count result.
return int32(count.Int64)
}

// If the fast count failed, returned NULL, or returned 0 try a full count.
// If the first fast count failed, returned NULL, or returned 0 try a fast count on partitioned table metadata.
if err := db.QueryRowContext(ctx, "SELECT sum(reltuples::BIGINT) FROM pg_class WHERE relname ilike 'storage%_pkey'").Scan(&count); err != nil {
logger.Warn("Error counting storage objects.", zap.Error(err))
if err == context.Canceled {
// If the context was cancelled do not attempt any further counts.
return 0
}
}
if count.Valid && count.Int64 != 0 {
// Use this count result.
return int32(count.Int64)
}

// If both fast counts failed, returned NULL, or returned 0 try a full count.
if err := db.QueryRowContext(ctx, "SELECT count(collection) FROM storage").Scan(&count); err != nil {
logger.Warn("Error counting storage objects.", zap.Error(err))
}
Expand Down
20 changes: 17 additions & 3 deletions server/console_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,19 +222,33 @@ func (s *ConsoleServer) ListUsers(ctx context.Context, in *console.ListUsersRequ

func countUsers(ctx context.Context, logger *zap.Logger, db *sql.DB) int32 {
var count sql.NullInt64
// First try a fast count on table metadata.
if err := db.QueryRowContext(ctx, "SELECT reltuples::BIGINT FROM pg_class WHERE relname = 'users'").Scan(&count); err != nil {
logger.Warn("Error counting users.", zap.Error(err))
if err == context.Canceled {
// If the context was cancelled do not attempt the full count.
// If the context was cancelled do not attempt any further counts.
return 0
}
}
if count.Valid && count.Int64 != 0 {
// Use fast count result.
// Use this count result.
return int32(count.Int64)
}

// If the fast count failed, returned NULL, or returned 0 try a full count.
// If the first fast count failed, returned NULL, or returned 0 try a fast count on partitioned table metadata.
if err := db.QueryRowContext(ctx, "SELECT sum(reltuples::BIGINT) FROM pg_class WHERE relname ilike 'users%_pkey'").Scan(&count); err != nil {
logger.Warn("Error counting users.", zap.Error(err))
if err == context.Canceled {
// If the context was cancelled do not attempt any further counts.
return 0
}
}
if count.Valid && count.Int64 != 0 {
// Use this count result.
return int32(count.Int64)
}

// If both fast counts failed, returned NULL, or returned 0 try a full count.
if err := db.QueryRowContext(ctx, "SELECT count(id) FROM users").Scan(&count); err != nil {
logger.Warn("Error counting users.", zap.Error(err))
}
Expand Down

0 comments on commit fdc4d3c

Please sign in to comment.