提交 e24398a2 编写于 作者: C CyrusNajmabadi

Be resilient to getting busy messages back from sqlite while retrieving the string table.

上级 8caf6101
......@@ -270,12 +270,16 @@ public override void Initialize(Solution solution)
""{DataColumnName}"" blob)");
// Also get the known set of string-to-id mappings we already have in the DB.
FetchStringTable(connection);
// Do this in one batch if possible.
var fetched = TryFetchStringTable(connection);
// If we weren't able to retrieve the entire string table in one batch,
// attempt to retrieve it for each
var fetchStringTable = !fetched;
// Try to bulk populate all the IDs we'll need for strings/projects/documents.
// Bulk population is much faster than trying to do everything individually.
// Note: we don't need to fetch the string table as we did it right above this.
BulkPopulateIds(connection, solution, fetchStringTable: false);
BulkPopulateIds(connection, solution, fetchStringTable);
}
}
}
......
......@@ -53,7 +53,12 @@ private void BulkPopulateProjectIds(SqlConnection connection, Project project, b
// the current string table, it will keep having problems trying to bulk populate.
if (fetchStringTable)
{
FetchStringTable(connection);
if (!TryFetchStringTable(connection))
{
// Weren't able to fetch the string table. Have to try this again
// later once the DB frees up.
return;
}
}
if (!BulkPopulateProjectIdsWorker(connection, project))
......
......@@ -12,23 +12,34 @@ internal partial class SQLitePersistentStorage
{
private readonly ConcurrentDictionary<string, int> _stringToIdMap = new ConcurrentDictionary<string, int>();
private void FetchStringTable(SqlConnection connection)
private bool TryFetchStringTable(SqlConnection connection)
{
using (var resettableStatement = connection.GetResettableStatement(
$@"select * from ""{StringInfoTableName}"""))
try
{
var statement = resettableStatement.Statement;
while (statement.Step() == Result.ROW)
using (var resettableStatement = connection.GetResettableStatement(
$@"select * from ""{StringInfoTableName}"""))
{
var id = statement.GetInt32At(columnIndex: 0);
var value = statement.GetStringAt(columnIndex: 1);
// Note that TryAdd won't overwrite an existing string->id pair. That's what
// we want. we don't want the strings we've allocated from the DB to be what
// we hold onto. We'd rather hold onto the strings we get from sources like
// the workspaces. This helps avoid unnecessary string instance duplication.
_stringToIdMap.TryAdd(value, id);
var statement = resettableStatement.Statement;
while (statement.Step() == Result.ROW)
{
var id = statement.GetInt32At(columnIndex: 0);
var value = statement.GetStringAt(columnIndex: 1);
// Note that TryAdd won't overwrite an existing string->id pair. That's what
// we want. we don't want the strings we've allocated from the DB to be what
// we hold onto. We'd rather hold onto the strings we get from sources like
// the workspaces. This helps avoid unnecessary string instance duplication.
_stringToIdMap.TryAdd(value, id);
}
}
return true;
}
catch (SqlException e) when (e.Result == Result.BUSY)
{
// Couldn't get access to sql database to fetch the string table.
// Try again later.
return false;
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册