Fix monitoring PF project list deadlock
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 37s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 37s
This commit is contained in:
@@ -270,7 +270,7 @@ func (a *App) ListProjects(ctx context.Context, ownerID int64) ([]Project, error
|
|||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
items := []Project{}
|
items := []Project{}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
p, err := a.scanProject(rows, false)
|
p, err := a.scanProject(ctx, rows, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -281,7 +281,7 @@ func (a *App) ListProjects(ctx context.Context, ownerID int64) ([]Project, error
|
|||||||
|
|
||||||
func (a *App) ProjectByID(ctx context.Context, ownerID, projectID int64, detail bool) (*Project, error) {
|
func (a *App) ProjectByID(ctx context.Context, ownerID, projectID int64, detail bool) (*Project, error) {
|
||||||
row := a.DB.QueryRowContext(ctx, projectSelect()+` WHERE p.id = ? AND p.owner_id = ?`, projectID, ownerID)
|
row := a.DB.QueryRowContext(ctx, projectSelect()+` WHERE p.id = ? AND p.owner_id = ?`, projectID, ownerID)
|
||||||
p, err := a.scanProject(row, detail)
|
p, err := a.scanProject(ctx, row, detail)
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
return nil, ErrNotFound
|
return nil, ErrNotFound
|
||||||
}
|
}
|
||||||
@@ -435,19 +435,25 @@ func projectSelect() string {
|
|||||||
(SELECT count(*) FROM competitor_listings l WHERE l.project_id = p.id),
|
(SELECT count(*) FROM competitor_listings l WHERE l.project_id = p.id),
|
||||||
(SELECT count(*) FROM competitor_listings l WHERE l.project_id = p.id AND l.status IN ('ACTIVE','active')),
|
(SELECT count(*) FROM competitor_listings l WHERE l.project_id = p.id AND l.status IN ('ACTIVE','active')),
|
||||||
(SELECT count(*) FROM competitor_listings l WHERE l.project_id = p.id AND l.status IN ('REMOVED','removed')),
|
(SELECT count(*) FROM competitor_listings l WHERE l.project_id = p.id AND l.status IN ('REMOVED','removed')),
|
||||||
(SELECT min(l.current_price) FROM competitor_listings l WHERE l.project_id = p.id AND l.status IN ('ACTIVE','active') AND l.current_price IS NOT NULL)
|
(SELECT min(l.current_price) FROM competitor_listings l WHERE l.project_id = p.id AND l.status IN ('ACTIVE','active') AND l.current_price IS NOT NULL),
|
||||||
FROM projects p`
|
e.id, e.name, e.portal_user_id, e.tg_chat_id, e.tg_username, e.created_at,
|
||||||
|
(SELECT count(*) FROM projects owner_p WHERE owner_p.owner_id = e.id) AS owner_projects_total
|
||||||
|
FROM projects p
|
||||||
|
LEFT JOIN employees e ON e.id = p.owner_id`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) scanProject(row rowScanner, detail bool) (*Project, error) {
|
func (a *App) scanProject(ctx context.Context, row rowScanner, detail bool) (*Project, error) {
|
||||||
var p Project
|
var p Project
|
||||||
var deal string
|
var deal string
|
||||||
var price, size, minPrice sql.NullFloat64
|
var price, size, minPrice sql.NullFloat64
|
||||||
var notes, permit, building, ourURL, created, checked sql.NullString
|
var notes, permit, building, ourURL, created, checked sql.NullString
|
||||||
var bedrooms sql.NullInt64
|
var bedrooms sql.NullInt64
|
||||||
|
var ownerID, ownerProjectsTotal sql.NullInt64
|
||||||
|
var ownerName, ownerPortalID, ownerChatID, ownerUsername, ownerCreated sql.NullString
|
||||||
if err := row.Scan(
|
if err := row.Scan(
|
||||||
&p.ID, &p.Title, &deal, &price, ¬es, &permit, &building, &bedrooms, &size, &ourURL,
|
&p.ID, &p.Title, &deal, &price, ¬es, &permit, &building, &bedrooms, &size, &ourURL,
|
||||||
&p.OwnerID, &created, &checked, &p.ListingsTotal, &p.ListingsActive, &p.ListingsRemoved, &minPrice,
|
&p.OwnerID, &created, &checked, &p.ListingsTotal, &p.ListingsActive, &p.ListingsRemoved, &minPrice,
|
||||||
|
&ownerID, &ownerName, &ownerPortalID, &ownerChatID, &ownerUsername, &ownerCreated, &ownerProjectsTotal,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -462,11 +468,19 @@ func (a *App) scanProject(row rowScanner, detail bool) (*Project, error) {
|
|||||||
p.CreatedAt = timeOut(created)
|
p.CreatedAt = timeOut(created)
|
||||||
p.LastCheckedAt = timeOut(checked)
|
p.LastCheckedAt = timeOut(checked)
|
||||||
p.MinCompetitorPrice = nullableFloat(minPrice)
|
p.MinCompetitorPrice = nullableFloat(minPrice)
|
||||||
if owner, err := a.EmployeeByID(context.Background(), p.OwnerID); err == nil {
|
if ownerID.Valid {
|
||||||
p.Owner = owner
|
p.Owner = &Employee{
|
||||||
|
ID: ownerID.Int64,
|
||||||
|
Name: ownerName.String,
|
||||||
|
PortalUserID: nullableString(ownerPortalID),
|
||||||
|
TGChatID: nullableString(ownerChatID),
|
||||||
|
TGUsername: nullableString(ownerUsername),
|
||||||
|
ProjectsTotal: nullIntValue(ownerProjectsTotal),
|
||||||
|
CreatedAt: timeOut(ownerCreated),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if detail {
|
if detail {
|
||||||
listings, err := a.ListingsForProject(context.Background(), p.ID, true)
|
listings, err := a.ListingsForProject(ctx, p.ID, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -480,22 +494,29 @@ func (a *App) ListingsForProject(ctx context.Context, projectID int64, withHisto
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
|
||||||
items := []Listing{}
|
items := []Listing{}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
item, err := scanListing(rows, false)
|
item, err := scanListing(rows, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
items = append(items, *item)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
rows.Close()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rows.Close()
|
||||||
if withHistory {
|
if withHistory {
|
||||||
item.PriceHistory, err = a.PriceHistory(ctx, item.ID)
|
for i := range items {
|
||||||
|
history, err := a.PriceHistory(ctx, items[i].ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
items[i].PriceHistory = history
|
||||||
}
|
}
|
||||||
items = append(items, *item)
|
|
||||||
}
|
}
|
||||||
return items, rows.Err()
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) PriceHistory(ctx context.Context, listingID int64) ([]PricePoint, error) {
|
func (a *App) PriceHistory(ctx context.Context, listingID int64) ([]PricePoint, error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user