Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions accounts.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package main

import (
"container/ring"
"errors"
"fmt"
"sync"
"time"

"github.com/distributeddesigns/currency"
)
Expand All @@ -16,13 +19,22 @@ type account struct {
portfolio portfolio
pendingBuys txStack
pendingSells txStack
summary *ring.Ring
sync.Mutex
}

const (
summarySize = 20
)

// newAccountForUser creates an empty account for the given user
func newAccountForUser(userID string) *account {
var ac = account{userID: userID}
ac.portfolio = make(portfolio)
ac.summary = ring.New(summarySize)

ac.AddSummaryItem("Created")

return &ac
}

Expand All @@ -31,6 +43,7 @@ func (ac *account) AddFunds(amount currency.Currency) {
consoleLog.Debugf("Old balance for %s is %s", ac.userID, ac.balance)

ac.balance.Add(amount)
ac.AddSummaryItem("Added " + amount.String())

consoleLog.Debugf("New balance for %s is %s", ac.userID, ac.balance)
}
Expand All @@ -40,6 +53,9 @@ func (ac *account) RemoveFunds(amount currency.Currency) error {
consoleLog.Debugf("Old balance for %s is %s", ac.userID, ac.balance)

err := ac.balance.Sub(amount)
if err != nil {
ac.AddSummaryItem("Removed " + amount.String())
}

consoleLog.Debugf("New balance for %s is %s", ac.userID, ac.balance)

Expand All @@ -52,6 +68,7 @@ func (ac *account) AddStock(stock string, quantity uint64) {
ac.userID, ac.portfolio[stock], stock)

ac.portfolio[stock] += quantity
ac.AddSummaryItem(fmt.Sprintf("Added %dx%s", quantity, stock))

consoleLog.Debugf("New portfolio for %s: %d x %s",
ac.userID, ac.portfolio[stock], stock)
Expand All @@ -68,6 +85,7 @@ func (ac *account) RemoveStock(stock string, quantity uint64) error {
ac.userID, ac.portfolio[stock], stock)

ac.portfolio[stock] -= quantity
ac.AddSummaryItem(fmt.Sprintf("Removed %dx%s", quantity, stock))

consoleLog.Debugf("New portfolio for %s: %d x %s",
ac.userID, ac.portfolio[stock], stock)
Expand All @@ -78,6 +96,7 @@ func (ac *account) RemoveStock(stock string, quantity uint64) error {
// PruneExpiredTxs will remove all pendingTxs that are expired
func (ac *account) PruneExpiredTxs() {
ac.Lock()
ac.AddSummaryItem("Starting expired TX cleanup")
expiredBuys := ac.pendingBuys.SplitExpired()
expiredSells := ac.pendingSells.SplitExpired()
ac.Unlock()
Expand All @@ -89,4 +108,33 @@ func (ac *account) PruneExpiredTxs() {
for _, sell := range *expiredSells {
sell.RollBack()
}

ac.AddSummaryItem("Finished expired TX cleanup")
}

type summaryItem struct {
loggedAt time.Time
message string
}

func (ac *account) AddSummaryItem(s string) {
// Since ring.Do() always goes _forward_ we want to make sure the forward
// order of elements is newest -> oldest. This saves us a reverse after
// we convert the ring to a slice.
ac.summary = ac.summary.Prev()
ac.summary.Value = summaryItem{time.Now(), s}
}

// GetSummary returns a list of the user's most recent account activities,
// sorted newest to oldest
func (ac *account) GetSummary() []summaryItem {
s := make([]summaryItem, 0)

ac.summary.Do(func(node interface{}) {
if node != nil {
s = append(s, node.(summaryItem))
}
})
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty gross (lots of memory allocation!) but I can't find a nice way to shrink slices. I want to only return non-emptysummaryItems...


return s
}
1 change: 1 addition & 0 deletions commands_add.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ func (a addCmd) Execute() {
consoleLog.Infof("Adding %s to %s", a.amount, a.userID)
acct.Lock()
acct.AddFunds(a.amount)
acct.AddSummaryItem("Finished " + a.Name())
acct.Unlock()

consoleLog.Notice(" [✔] Finished", a.Name())
Expand Down
3 changes: 3 additions & 0 deletions commands_buy.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ func (b buyCmd) Execute() {
abortTxOnError(err, "This should be impossible!")
acct.pendingBuys.Push(b)

acct.AddSummaryItem("Finished " + b.Name())
consoleLog.Notice(" [✔] Finished", b.Name())
}

Expand All @@ -125,6 +126,7 @@ func (b buyCmd) Commit() {
acct := accountStore[b.userID]
acct.Lock()
acct.AddStock(b.stock, b.quantityToBuy)
acct.AddSummaryItem("Commited " + b.Name())
acct.Unlock()
}

Expand All @@ -133,6 +135,7 @@ func (b buyCmd) RollBack() {
acct := accountStore[b.userID]
acct.Lock()
acct.AddFunds(b.purchaseAmount)
acct.AddSummaryItem("Rolled back " + b.Name())
acct.Unlock()
}

Expand Down
1 change: 1 addition & 0 deletions commands_cancelBuy.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,6 @@ func (cb cancelBuyCmd) Execute() {

pendingBuy.RollBack()

acct.AddSummaryItem("Finished " + cb.Name())
consoleLog.Notice(" [✔] Finished", cb.Name())
}
1 change: 1 addition & 0 deletions commands_cancelSell.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,6 @@ func (cs cancelSellCmd) Execute() {

pendingSell.RollBack()

acct.AddSummaryItem("Finished " + cs.Name())
consoleLog.Notice(" [✔] Finished", cs.Name())
}
1 change: 1 addition & 0 deletions commands_commitBuy.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,6 @@ func (cb commitBuyCmd) Execute() {

pendingBuy.Commit()

acct.AddSummaryItem("Finished " + cb.Name())
consoleLog.Notice(" [✔] Finished", cb.Name())
}
1 change: 1 addition & 0 deletions commands_commitSell.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,6 @@ func (cs commitSellCmd) Execute() {

pendingSell.Commit()

acct.AddSummaryItem("Finished " + cs.Name())
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The repetition is bothering me...

consoleLog.Notice(" [✔] Finished", cs.Name())
}
13 changes: 12 additions & 1 deletion commands_displaySummary.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,16 @@ func (ds displaySummaryCmd) ToAuditEvent() types.AuditEvent {
}

func (ds displaySummaryCmd) Execute() {
consoleLog.Warning("Not implemented: DISPLAY_SUMMARY")
abortTxIfNoAccount(ds.userID)

acct := accountStore[ds.userID]
acct.Lock()
defer acct.Unlock()

_ = acct.GetSummary()

// TODO: Send other account data. Format will depend on FE implementation.

acct.AddSummaryItem("Finished " + ds.Name())
consoleLog.Notice(" [✔] Finished", ds.Name())
}
5 changes: 5 additions & 0 deletions commands_dumplog.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ func (dl dumplogCmd) ToAuditEvent() types.AuditEvent {
}

func (dl dumplogCmd) Execute() {
abortTxIfNoAccount(dl.userID)

dlr := types.DumplogRequest{
UserID: dl.userID,
Filename: dl.filename,
Expand All @@ -98,6 +100,9 @@ func (dl dumplogCmd) Execute() {

consoleLog.Debug("Dumplog requested as", dlr.Filename)

acct := accountStore[dl.userID]
acct.AddSummaryItem("Finished " + dl.Name())

consoleLog.Notice(" [✔] Finished", dl.Name())
}

Expand Down
5 changes: 5 additions & 0 deletions commands_quote.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ func (q quoteCmd) ToAuditEvent() types.AuditEvent {
}

func (q quoteCmd) Execute() {
abortTxIfNoAccount(q.userID)

qr := types.QuoteRequest{
Stock: q.stock,
UserID: q.userID,
Expand All @@ -65,5 +67,8 @@ func (q quoteCmd) Execute() {
// TODO: actually return a response
_ = getQuote(qr)

acct := accountStore[q.userID]
acct.AddSummaryItem("Finished " + q.Name())

consoleLog.Notice(" [✔] Finished", q.Name())
}
5 changes: 4 additions & 1 deletion commands_sell.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func (s sellCmd) Execute() {
quantityToSell, profit := q.Price.FitsInto(s.amount)
consoleLog.Debugf("Want to sell %d stock", quantityToSell)
if quantityToSell < 1 {
abortTx(s.Name() + "Cannot sell less than one stock")
abortTx(s.Name() + " Cannot sell less than one stock")
}

// If yes...
Expand All @@ -116,6 +116,7 @@ func (s sellCmd) Execute() {
abortTxOnError(err, s.Name())
acct.pendingSells.Push(s)

acct.AddSummaryItem("Finished " + s.Name())
consoleLog.Notice(" [✔] Finished", s.Name())
}

Expand All @@ -124,6 +125,7 @@ func (s sellCmd) Commit() {
acct := accountStore[s.userID]
acct.Lock()
acct.AddFunds(s.profit)
acct.AddSummaryItem("Commited " + s.Name())
acct.Unlock()
}

Expand All @@ -132,6 +134,7 @@ func (s sellCmd) RollBack() {
acct := accountStore[s.userID]
acct.Lock()
acct.AddStock(s.stock, s.quantityToSell)
acct.AddSummaryItem("Rolled back " + s.Name())
acct.Unlock()
}

Expand Down