Skip to content

Commit

Permalink
cleanup storage threshold logic
Browse files Browse the repository at this point in the history
  • Loading branch information
LucRoy committed May 17, 2023
1 parent 1a87d30 commit aefa166
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 50 deletions.
55 changes: 35 additions & 20 deletions api/v1/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ func (s *apiV1) handleAddIpfs(c echo.Context, u *util.User) error {
func (s *apiV1) handleAddCar(c echo.Context, u *util.User) error {
ctx := c.Request().Context()

contentLength := c.Request().ContentLength
//contentLength := c.Request().ContentLength

if err := util.ErrorIfContentAddingDisabled(s.isContentAddingDisabled(u)); err != nil {
return err
Expand All @@ -382,13 +382,13 @@ func (s *apiV1) handleAddCar(c echo.Context, u *util.User) error {
return s.redirectContentAdding(c, u)
}

var usc util.UsersStorageCapacity
if err := usc.GetUserStorageCapacity(u, s.db); err != nil {
// Get user storage capacity
usc, err := s.getUserStorageCapacity(u)
if err != nil {
return err
}

// Increase and validate that the user storage threshold has not reached limit
if !usc.IncreaseAndValidateThreshold(contentLength) {
if !usc.ValidateThreshold() {
return &util.HttpError{
Code: http.StatusBadRequest,
Reason: util.ERR_CONTENT_SIZE_OVER_LIMIT,
Expand Down Expand Up @@ -486,9 +486,6 @@ func (s *apiV1) handleAddCar(c echo.Context, u *util.User) error {
return err
}

// Update user storage capacity with new value
s.db.Save(&usc)

go func() {
if err := s.nd.Provider.Provide(rootCID); err != nil {
s.log.Warnf("failed to announce providers: %s", err)
Expand All @@ -511,6 +508,24 @@ func (s *apiV1) loadCar(ctx context.Context, bs blockstore.Blockstore, r io.Read
return car.LoadCar(ctx, bs, r)
}

func (s *apiV1) getUserStorageCapacity(user *util.User) (*util.UsersStorageCapacity, error) {
var usc *util.UsersStorageCapacity
err := s.db.First(&usc, "user_id = ?", user.ID).Error

if err != nil || usc.IsSyncNeeded() {
var usage util.Utilization
if err := s.db.Raw(`SELECT (SELECT SUM(size) FROM contents where user_id = ? AND created_at >= ? AND NOT aggregate AND active AND deleted_at IS NULL) as total_size`, user.ID, util.CutOverUtilizationDate).
Scan(&usage).Error; err != nil {
return usc, err
}
usc.Size = usage.TotalSize
usc.LastSyncAt = time.Now()
s.db.Save(&usc)
}

return usc, err
}

// handleAdd godoc
// @Summary Add new content
// @Description This endpoint is used to upload new content.
Expand Down Expand Up @@ -558,13 +573,13 @@ func (s *apiV1) handleAdd(c echo.Context, u *util.User) error {
return err
}

var usc util.UsersStorageCapacity
if err := usc.GetUserStorageCapacity(u, s.db); err != nil {
// Get user storage capacity
usc, err := s.getUserStorageCapacity(u)
if err != nil {
return err
}

// Increase and validate that the user storage threshold has not reached limit
if !usc.IncreaseAndValidateThreshold(mpf.Size) {
if !usc.ValidateThreshold() {
return &util.HttpError{
Code: http.StatusBadRequest,
Reason: util.ERR_CONTENT_SIZE_OVER_LIMIT,
Expand Down Expand Up @@ -891,9 +906,9 @@ func (s *apiV1) handleGetContent(c echo.Context, u *util.User) error {
return err
}

if err := util.IsContentOwner(u.ID, content.UserID); err != nil {
return err
}
//if err := util.IsContentOwner(u.ID, content.UserID); err != nil {
// return err
//}

return c.JSON(http.StatusOK, content)
}
Expand Down Expand Up @@ -2895,8 +2910,8 @@ func (s *apiV1) handleGetUserStats(c echo.Context, u *util.User) error {
// @Failure 500 {object} util.HttpError
// @Router /user/utilization [get]
func (s *apiV1) handleGetUserUtilization(c echo.Context, u *util.User) error {
var usc util.UsersStorageCapacity
if err := usc.GetUserStorageCapacity(u, s.db); err != nil {
usc, err := s.getUserStorageCapacity(u)
if err != nil {
return err
}
return c.JSON(http.StatusOK, usc)
Expand Down Expand Up @@ -4564,12 +4579,12 @@ func (s *apiV1) handleCreateContent(c echo.Context, u *util.User) error {
return err
}

var usc util.UsersStorageCapacity
if err := usc.GetUserStorageCapacity(u, s.db); err != nil {
// Get user storage capacity
usc, err := s.getUserStorageCapacity(u)
if err != nil {
return err
}

// Increase and validate that the user storage threshold has not reached limit
if !usc.ValidateThreshold() {
return &util.HttpError{
Code: http.StatusBadRequest,
Expand Down
6 changes: 3 additions & 3 deletions api/v1/pinning.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,12 +262,12 @@ func (s *apiV1) handleAddPin(c echo.Context, u *util.User) error {
overwrite = true
}

var usc util.UsersStorageCapacity
if err := usc.GetUserStorageCapacity(u, s.db); err != nil {
// Get user storage capacity
usc, err := s.getUserStorageCapacity(u)
if err != nil {
return err
}

// Increase and validate that the user storage threshold has not reached limit
if !usc.ValidateThreshold() {
return &util.HttpError{
Code: http.StatusBadRequest,
Expand Down
30 changes: 3 additions & 27 deletions util/users_storage_capacity.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,39 +21,15 @@ type Utilization struct {

// CutOverUtilizationDate All content uploaded pass this date will count toward your user storage capacity
const CutOverUtilizationDate = "2023-05-12 00:00:00"

func (usc *UsersStorageCapacity) GetUserStorageCapacity(user *User, db *gorm.DB) error {
if err := db.First(&usc, "user_id = ?", user.ID).Error; err != nil {
usc.UserId = user.ID
db.Create(&usc)
}
if isSyncNeeded(usc.LastSyncAt) {
var usage Utilization
if err := db.Raw(`SELECT (SELECT SUM(size) FROM contents where user_id = ? AND created_at >= ? AND NOT aggregate AND active AND deleted_at IS NULL) as total_size`, user.ID, CutOverUtilizationDate).
Scan(&usage).Error; err != nil {
return err
}
usc.Size = usage.TotalSize
usc.LastSyncAt = time.Now()
db.Save(&usc)
}
return nil
}

func (usc *UsersStorageCapacity) IncreaseAndValidateThreshold(add int64) bool {
usc.Size += add
return usc.Size <= usc.HardLimit
}
const SyncRefreshInHours = 24

func (usc *UsersStorageCapacity) ValidateThreshold() bool {
return usc.Size <= usc.HardLimit
}

const SyncRefreshInHours = 24

func isSyncNeeded(t time.Time) bool {
func (usc *UsersStorageCapacity) IsSyncNeeded() bool {
now := time.Now().UTC()
duration := now.Sub(t.UTC())
duration := now.Sub(usc.LastSyncAt.UTC())
refresh := SyncRefreshInHours * time.Hour
return duration >= refresh
}

0 comments on commit aefa166

Please sign in to comment.