Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split FE, and now also make user on socket connect #35

Open
wants to merge 17 commits into
base: frontend
Choose a base branch
from
Open
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
72 changes: 71 additions & 1 deletion accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package main

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

"github.com/distributeddesigns/currency"
types "github.com/distributeddesigns/shared_types"
"github.com/gorilla/websocket"
)

Expand Down Expand Up @@ -39,6 +41,10 @@ func newAccountForUser(userID string) *account {
return &ac
}

func (ac *account) toCSV() string {
return fmt.Sprintf("%s,%.2f", ac.userID, ac.balance.ToFloat())
}

// AddFunds : Increases the balance of the account
func (ac *account) AddFunds(amount currency.Currency) {
consoleLog.Debugf("Old balance for %s is %s", ac.userID, ac.balance)
Expand Down Expand Up @@ -118,13 +124,77 @@ func (ac *account) PruneExpiredTxs() {
}
}

type pendingATXState struct {
Stock string `json:"stock"`
Amount string `json:"amount"`
Trigger string `json:"trigger"`
Action string `json:"action"`
}

func serializeATX(autoTx types.AutoTxInit) pendingATXState {
return pendingATXState{
Stock: autoTx.AutoTxKey.Stock,
Action: autoTx.AutoTxKey.Action,
Amount: autoTx.Amount.String(),
Trigger: autoTx.Trigger.String(),
}
}

type accountState struct {
Balance string `json:"balance"`
Portfolio map[string]uint64 `json:"portfolio"`
PendingBuys []pendingTxState `json:"pendingBuys"`
PendingSells []pendingTxState `json:"pendingSells"`
AutoTx []pendingATXState `json:"pendingATX"`
}

func (ac *account) GetState() accountState {
pendingBuys := make([]pendingTxState, len(ac.pendingBuys))
for i, pb := range ac.pendingBuys {
pendingBuys[i] = pb.GetState()
}

pendingSells := make([]pendingTxState, len(ac.pendingSells))
for i, ps := range ac.pendingSells {
pendingSells[i] = ps.GetState()
}

pendingATX := make([]pendingATXState, 0)
for k, v := range workATXStore {
if k.UserID == ac.userID {
serTx := serializeATX(v)
pendingATX = append(pendingATX, serTx)
}
}

return accountState{
Balance: ac.balance.String(),
Portfolio: ac.portfolio,
PendingBuys: pendingBuys,
PendingSells: pendingSells,
AutoTx: pendingATX,
}
}

type eventMessage struct {
Account accountState `json:"account"`
Message string `json:"message"`
}

func (ac *account) PushEvent(message string) {
socket, found := userSocketmap[ac.userID]
if !found {
consoleLog.Errorf("User %s is not subscribed to a socket connection", ac.userID)
return
}
socket.WriteMessage(websocket.TextMessage, []byte(message))

payload, err := json.Marshal(&eventMessage{ac.GetState(), message})
if err != nil {
consoleLog.Errorf("Failed to json-ify %+v, %s", ac, message)
return
}

socket.WriteMessage(websocket.TextMessage, payload)
}

type summaryItem struct {
Expand Down
8 changes: 8 additions & 0 deletions commands_buy.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,11 @@ func (b buyCmd) RollBack() {
func (b buyCmd) IsExpired() bool {
return time.Now().After(b.expiresAt)
}

func (b buyCmd) GetState() pendingTxState {
return pendingTxState{
Stock: b.stock,
Amount: b.purchaseAmount.String(),
ExpiresAt: b.expiresAt.Format("15:04:05 Jan _2"),
}
}
8 changes: 8 additions & 0 deletions commands_sell.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,11 @@ func (s sellCmd) RollBack() {
func (s sellCmd) IsExpired() bool {
return time.Now().After(s.expiresAt)
}

func (s sellCmd) GetState() pendingTxState {
return pendingTxState{
Stock: s.stock,
Amount: s.profit.String(),
ExpiresAt: s.expiresAt.Format("15:04:05 Jan _2"),
}
}
13 changes: 10 additions & 3 deletions incomingTxWatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,20 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
}
// frontend handshake to get user and hook them into the userMap for sockets
_, message, err := conn.ReadMessage()
userID := string(message)
failOnError(err, "Failed to handshake")
fmt.Printf("Handshake from client is %s\n", message)
userSocket, found := userSocketmap[string(message)]
fmt.Printf("Handshake from client is %s\n", userID)
userSocket, found := userSocketmap[string(userID)]
if found {
userSocket.Close()
}
userSocketmap[string(message)] = conn
userSocketmap[string(userID)] = conn
if _, accountExists := accountStore[userID]; !accountExists {
consoleLog.Infof("Creating account for %s", userID)
accountStore[userID] = newAccountForUser(userID)
}
accountStore[userID].PushEvent("") //shove for userdata
//conn.WriteMessage(websocket.TextMessage, []byte(`{"account": "`+accountStore[userID].toCSV()+`", "message": null}`))
}

func incomingTxWatcher() {
Expand Down
7 changes: 7 additions & 0 deletions pendingTx.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package main

type pendingTxState struct {
Stock string `json:"stock"`
Amount string `json:"amount"`
ExpiresAt string `json:"expiresAt"`
}

type pendingTx interface {
Commit()
RollBack()
IsExpired() bool
GetState() pendingTxState
}
2 changes: 1 addition & 1 deletion receiveAutoTx.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func receiveAutoTx() {
autoTxFilled, err := types.ParseAutoTxFilled(string(d.Body[:]))
failOnError(err, "Failed to parse autoTxInit")
consoleLog.Debugf("AutoTxFilled is : %+v\n", autoTxFilled)
fulfilAutoTx(autoTxFilled)
updateAccount(autoTxFilled)
}
fmt.Printf("AutoTxWorker Receiver Spinning\n")
}
30 changes: 20 additions & 10 deletions sendAutoTx.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ import (
"github.com/streadway/amqp"
)

func fulfilAutoTx(autoTxFilled types.AutoTxFilled) {
return
}

func updateAccount(autoTxFilled types.AutoTxFilled) {
// TODO: Do account add and lock here, needs rebase
accountStore[autoTxFilled.AutoTxKey.UserID].Lock()
accountStore[autoTxFilled.AutoTxKey.UserID].AddFunds(autoTxFilled.AddFunds)
accountStore[autoTxFilled.AutoTxKey.UserID].AddStock(autoTxFilled.AutoTxKey.Stock, uint64(autoTxFilled.AddStocks))
accountStore[autoTxFilled.AutoTxKey.UserID].Unlock()
return
}

Expand All @@ -37,12 +36,23 @@ func sendAutoTx() {
}

if validTrigger {
// TODO: DO MATH FOR FILLED TRANS
curr, err := currency.NewFromFloat(0.00)
failOnError(err, "Failed to parse currency")
var filledStock uint
var filledCash currency.Currency
if autoTxKey.Action == "Buy" {
filledStock, filledCash = quote.Price.FitsInto(autoTxInit.Amount)
failOnError(err, "Failed to parse currency")
} else {
numStock, remCash := autoTxInit.Trigger.FitsInto(autoTxInit.Amount) // amount of stock we reserved from their port
filledCash = quote.Price
err = filledCash.Mul(float64(numStock))
filledCash.Add(remCash) // Re-add the unfilled value
filledStock = 0
failOnError(err, "Failed to parse currency")
}

autoTxFilled := types.AutoTxFilled{
AddFunds: curr,
AddStocks: uint(0),
AddFunds: filledCash,
AddStocks: filledStock,
AutoTxKey: autoTxKey,
}
updateAccount(autoTxFilled)
Expand Down
Loading