mirror of
https://github.com/bitwarden/server.git
synced 2025-05-20 11:04:31 -05:00
Added GetTakeCount
helper to break down large arrays into manageable sizes for documentdb requests (current max limit of 512kb per request).
This commit is contained in:
parent
4c4f803c1f
commit
79f9f60a78
@ -34,21 +34,21 @@ namespace Bit.Core.Repositories.DocumentDB
|
||||
|
||||
public async Task UpdateDirtyCiphersAsync(IEnumerable<dynamic> ciphers)
|
||||
{
|
||||
// Make sure we are dealing with cipher types since we accept any via dynamic.
|
||||
var cleanedCiphers = ciphers.Where(c => c is Cipher);
|
||||
if(cleanedCiphers.Count() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var takeCount = DocumentDBHelpers.GetTakeCount(ciphers, 500);
|
||||
|
||||
await DocumentDBHelpers.ExecuteWithRetryAsync(async () =>
|
||||
{
|
||||
// Make sure we are dealing with cipher types since we accept any via dynamic.
|
||||
var cleanedCiphers = ciphers.Where(c => c is Cipher);
|
||||
if(cleanedCiphers.Count() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var userId = ((Cipher)cleanedCiphers.First()).UserId;
|
||||
StoredProcedureResponse<int> sprocResponse = await Client.ExecuteStoredProcedureAsync<int>(
|
||||
ResolveSprocIdLink(userId, "updateDirtyCiphers"),
|
||||
// TODO: Figure out how to better determine the max number of document to send without
|
||||
// going over 512kb limit for DocumentDB. 50 could still be too large in some cases.
|
||||
cleanedCiphers.Take(50),
|
||||
cleanedCiphers.Take(takeCount),
|
||||
userId);
|
||||
|
||||
var replacedCount = sprocResponse.Response;
|
||||
@ -61,21 +61,21 @@ namespace Bit.Core.Repositories.DocumentDB
|
||||
|
||||
public async Task CreateAsync(IEnumerable<dynamic> ciphers)
|
||||
{
|
||||
// Make sure we are dealing with cipher types since we accept any via dynamic.
|
||||
var cleanedCiphers = ciphers.Where(c => c is Cipher);
|
||||
if(cleanedCiphers.Count() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var takeCount = DocumentDBHelpers.GetTakeCount(ciphers, 500);
|
||||
|
||||
await DocumentDBHelpers.ExecuteWithRetryAsync(async () =>
|
||||
{
|
||||
// Make sure we are dealing with cipher types since we accept any via dynamic.
|
||||
var cleanedCiphers = ciphers.Where(c => c is Cipher);
|
||||
if(cleanedCiphers.Count() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var userId = ((Cipher)cleanedCiphers.First()).UserId;
|
||||
StoredProcedureResponse<int> sprocResponse = await Client.ExecuteStoredProcedureAsync<int>(
|
||||
ResolveSprocIdLink(userId, "bulkCreate"),
|
||||
// TODO: Figure out how to better determine the max number of document to send without
|
||||
// going over 512kb limit for DocumentDB. 50 could still be too large in some cases.
|
||||
cleanedCiphers.Take(50));
|
||||
cleanedCiphers.Take(takeCount));
|
||||
|
||||
var createdCount = sprocResponse.Response;
|
||||
if(createdCount != cleanedCiphers.Count())
|
||||
|
@ -1,7 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Azure.Documents;
|
||||
using Microsoft.Azure.Documents.Client;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Repositories.DocumentDB.Utilities
|
||||
{
|
||||
@ -58,6 +62,24 @@ namespace Bit.Core.Repositories.DocumentDB.Utilities
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetTakeCount(IEnumerable<object> docs, int maxSizeKb = 500)
|
||||
{
|
||||
var takeCount = docs.Count();
|
||||
while(takeCount > 1)
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(docs.Take(takeCount)));
|
||||
if((bytes.Length / 1000) <= maxSizeKb)
|
||||
{
|
||||
// array is is small enough
|
||||
break;
|
||||
}
|
||||
|
||||
takeCount = Convert.ToInt32(Math.Ceiling((double)takeCount / 2));
|
||||
}
|
||||
|
||||
return takeCount;
|
||||
}
|
||||
|
||||
private static async Task HandleDocumentClientExceptionAsync(DocumentClientException e, int retryCount, int? retryMax)
|
||||
{
|
||||
if(retryMax.HasValue && retryCount >= retryMax.Value)
|
||||
|
Loading…
x
Reference in New Issue
Block a user