public static async Task <int> TryClaimTx(PlatformId platformId, User user, BitcornContext dbContext) { if (user == null) { user = await BitcornUtils.GetUserForPlatform(platformId, dbContext).FirstOrDefaultAsync(); } if (user == null) { return(0); } bool lockApplied = false; try { if (UserLockCollection.Lock(user)) { lockApplied = true; } else { return(0); } var now = DateTime.Now; var txs = await dbContext.UnclaimedTx.Where(u => u.Platform == platformId.Platform && u.ReceiverPlatformId == platformId.Id && !u.Claimed && !u.Refunded && u.Expiration > now).ToArrayAsync(); var sql = new StringBuilder(); var pk = nameof(UserWallet.UserId); foreach (var tx in txs) { tx.Claimed = true; var log = new CornTx(); log.Amount = tx.Amount; log.Platform = tx.Platform; log.ReceiverId = user.UserId; log.SenderId = tx.SenderUserId; log.Timestamp = tx.Timestamp; log.TxGroupId = Guid.NewGuid().ToString(); log.TxType = tx.TxType; log.UnclaimedTx.Add(tx); dbContext.CornTx.Add(log); sql.Append(TxUtils.ModifyNumber(nameof(UserWallet), nameof(UserWallet.Balance), tx.Amount, '+', pk, user.UserId)); sql.Append(TxUtils.ModifyNumber(nameof(UserStat), nameof(UserStat.AmountOfTipsReceived), 1, '+', pk, user.UserId)); sql.Append(TxUtils.ModifyNumber(nameof(UserStat), nameof(UserStat.TotalReceivedBitcornTips), tx.Amount, '+', pk, user.UserId)); sql.Append(TxUtils.UpdateNumberIfTop(nameof(UserStat), nameof(UserStat.LargestReceivedBitcornTip), tx.Amount, pk, user.UserId)); sql.Append(TxUtils.ModifyNumber(nameof(UserStat), nameof(UserStat.AmountOfTipsSent), 1, '+', pk, tx.SenderUserId)); sql.Append(TxUtils.ModifyNumber(nameof(UserStat), nameof(UserStat.TotalSentBitcornViaTips), tx.Amount, '+', pk, tx.SenderUserId)); sql.Append(TxUtils.UpdateNumberIfTop(nameof(UserStat), nameof(UserStat.LargestSentBitcornTip), tx.Amount, pk, tx.SenderUserId)); } if (txs.Length > 0) { await DbOperations.ExecuteSqlRawAsync(dbContext, sql.ToString()); await dbContext.SaveAsync(); } return(txs.Length); } catch (Exception e) { await BITCORNLogger.LogError(dbContext, e, JsonConvert.SerializeObject(platformId)); return(0); } finally { if (lockApplied) { UserLockCollection.Release(user); } } }
public static async Task <int> TryClaimTx(PlatformId platformId, User user, BitcornContext dbContext) { if (user == null) { user = await BitcornUtils.GetUserForPlatform(platformId, dbContext).FirstOrDefaultAsync(); } if (user == null) { return(0); } bool lockApplied = false; try { lock (LockUserAttribute.LockedUsers) { if (LockUserAttribute.LockedUsers.Contains(user.UserId)) { return(0); } lockApplied = LockUserAttribute.LockedUsers.Add(user.UserId); } var now = DateTime.Now; var txs = await dbContext.UnclaimedTx.Where(u => u.Platform == platformId.Platform && u.ReceiverPlatformId == platformId.Id && !u.Claimed && !u.Refunded && u.Expiration > now).ToArrayAsync(); var sql = new StringBuilder(); var pk = nameof(UserWallet.UserId); foreach (var tx in txs) { tx.Claimed = true; var log = new CornTx(); log.Amount = tx.Amount; log.Platform = tx.Platform; log.ReceiverId = user.UserId; log.SenderId = tx.SenderUserId; log.Timestamp = tx.Timestamp; log.TxGroupId = Guid.NewGuid().ToString(); log.TxType = tx.TxType; log.UnclaimedTx.Add(tx); dbContext.CornTx.Add(log); sql.Append(TxUtils.ModifyNumber(nameof(UserWallet), nameof(UserWallet.Balance), tx.Amount, '+', pk, user.UserId)); sql.Append(TxUtils.ModifyNumber(nameof(UserStat), nameof(UserStat.Tipped), 1, '+', pk, user.UserId)); sql.Append(TxUtils.ModifyNumber(nameof(UserStat), nameof(UserStat.TippedTotal), tx.Amount, '+', pk, user.UserId)); sql.Append(TxUtils.UpdateNumberIfTop(nameof(UserStat), nameof(UserStat.TopTipped), tx.Amount, pk, user.UserId)); sql.Append(TxUtils.ModifyNumber(nameof(UserStat), nameof(UserStat.Tip), 1, '+', pk, tx.SenderUserId)); sql.Append(TxUtils.ModifyNumber(nameof(UserStat), nameof(UserStat.TipTotal), tx.Amount, '+', pk, tx.SenderUserId)); sql.Append(TxUtils.UpdateNumberIfTop(nameof(UserStat), nameof(UserStat.TopTip), tx.Amount, pk, tx.SenderUserId)); } if (txs.Length > 0) { await dbContext.Database.ExecuteSqlRawAsync(sql.ToString()); await dbContext.SaveAsync(); } return(txs.Length); } catch (Exception e) { await BITCORNLogger.LogError(dbContext, e); return(0); } finally { if (lockApplied) { lock (LockUserAttribute.LockedUsers) { LockUserAttribute.LockedUsers.Remove(user.UserId); } } } }