// Stick it as a deferred statement in gouroutines to prevent the program from crashing. func Recover(daemonName string) { if e := recover(); e != nil { stack := string(debug.Stack()) errorString := fmt.Sprintf("[%s] %s\n%s", daemonName, e, stack) alert.Alert(errorString) } }
// Each coin should only have 1 processor. // This allows for more granular transactions. // NOTE: consider select ... for update when selecting the payments to use. // CONTRACT: call this in a goroutine, it won't stop until a fatal error. func Process(coin string) { defer Recover("Treasury::Process(" + coin + ")") for { // if privkey hasn't been seeded yet, then wait. if !hasHotPrivKey() { Warn("Please seed the master privKey for %v", account.GetHotMPK().PubKey) time.Sleep(60 * time.Second) continue } // Process sweep transactions // TODO: automatically figure out sweeps. // TODO: for now, get sweeps from admin. // Process user initiated withdrawals processed, err := ProcessUserWithdrawals(coin) if err != nil { // Notify admin of the error, will retry manually. alert.Alert(fmt.Sprintf("Withdrawals for %v stalled: %v", coin, err.Error())) continue } else if !processed { Info("Sleeping, no withdrawals to process") time.Sleep(30 * time.Second) continue } } }