Record Not Found


#1

I am writing a Windows service that updates data in Realm including deleting records that are no longer required. The code for this is;

using (var driverRealm = OpenRealm($"~/{RealmName}", user, userName))
{
	var session = driverRealm.GetSession();
	Thread.Sleep(250);
	AsyncContext.Run(() => session.WaitForDownloadAsync());

	RunServices runSvc = new RunServices(driverRealm);
	JobServices jobSvc = new JobServices(driverRealm);
	ServiceServices serviceSvc = new ServiceServices(driverRealm);

	...
	
	foreach (DataRow jobRow in dbJobs.Rows)
	{
		var jobId = jobRow.Field<Guid>("JobId").ToString();
		RemoveRealmJob(jobSvc, jobId);
		...
	}
}

private static void RemoveRealmJob(JobServices jobSvc, string jobId)
{
	var job = jobSvc.GetById(jobId);

	if (job == null)
		Service.LogException($"Failed to locate a realm Job record for ID \"{jobId}\"."));
	else
		jobSvc.Remove(job);
}

private static Realm OpenRealm(string realmName, User user, string path)
{
	Realm realm;
	var fileName = $"{realmName.Strip("~/", Extensions.StringExtensions.StripFrom.Start)}.realm";
	var config = ConnectionServices.GetRealmConfiguration(realmName, user, $"{appDirectory}Realm\\{path}", fileName);
	realm = ConnectionServices.ConnectToSyncServer(config);
	return realm;
}

public Job GetById(string id)
{
	//return realm.All<Job>().FirstOrDefault(x => x.JobId == id);

	//var job = realm.All<Job>().FirstOrDefault(x => x.JobId == id);
	//return job;

	var jobs = realm.All<Job>().ToList();
	var job = jobs.FirstOrDefault(x => x.JobId == id);
	return job;
}

public static FullSyncConfiguration GetRealmConfiguration(string realmName, User user, string path, string fileName)
{
	var serverUrl = new Uri(realmName, UriKind.Relative);
	FullSyncConfiguration config;
	config = new FullSyncConfiguration(serverUrl, user, $"{path}\\{fileName}")
	{
		ObjectClasses = new[] { typeof(Driver), typeof(Run), typeof(Job), typeof(Service), typeof(JobResponse), typeof(ServiceResponse) }
	};
	return config;
}

public static Realm ConnectToSyncServer(FullSyncConfiguration config)
{
	Realm realm;
	realm = Realm.GetInstance(config);
	return realm;
}

Intermittently the code doesn’t return a Job object in the GetById procedure even though both the ROS and local Realm contain the record in question;


#2

Is it possible the session has not fully updated before calling WaitForDownloadAsync?


#3

As part of debugging this issue, I built a list of Job IDs that weren’t found then after the initial procedure was run I repeated it with the list of missing IDs;

RemoveDeletedRecords(db);

if (MissedJobs.Count > 0)
{
	RemoveDeletedJobs(db, MissedJobs);
}

private static void RemoveDeletedJobs(SqlConnector db, List<string> missedJobs)
{
	StringBuilder jobIds = new StringBuilder();
	StringBuilder sql = new StringBuilder();

	foreach (var jobId in missedJobs)
		jobIds.Append($"'{jobId}', ");

	sql.Append("select distinct [t2].[DriverId]");
	sql.Append(" from [CrmRealmJob] as [t1] inner join [CrmRealmRun] as [t2] on [t1].[RunId] = [t2].[RunId]");
	sql.Append($" where [t1].[JobId] in ({jobIds.ToString().Trim().Strip(",", Extensions.StringExtensions.StripFrom.End)})");

	var drivers = db.GetQueryResults(sql.ToString());

	foreach (DataRow driverRow in drivers.Rows)
	{
		var driverId = driverRow.Field<Guid>("DriverId").ToString();
		var driver = GetDbDriver(db, driverId);
		var userName = driver.Field<string>("UserName");
		var user = GetRealmUser(db, driver);

		using (var driverRealm = OpenRealm($"~/{RealmName}", user, userName))
		{
			var session = realm.GetSession();
			Thread.Sleep(250);

			AsyncContext.Run(() => session.WaitForDownloadAsync());

			RunServices runSvc = new RunServices(driverRealm);
			JobServices jobSvc = new JobServices(driverRealm);
			ServiceServices serviceSvc = new ServiceServices(driverRealm);

			sql.Clear().Append($"select distinct [t1].[JobId] from [CrmRealmJob] as [t1] left join [CrmRealmStaging] as [t2] on [t1].[JobId] = [t2].[jobId] inner join [CrmRealmRun] as [t3] on [t1].[RunId] = [t3].[RunId] where [t2].[jobId] is null and [t3].[DriverId] = '{ driverId}'");
			var dbJobs = db.GetQueryResults(sql.ToString());

			foreach (DataRow jobRow in dbJobs.Rows)
			{
				var jobId = jobRow.Field<Guid>("JobId").ToString();

				if (RemoveRealmJob(jobSvc, serviceSvc, jobId))
				{
					sql.Clear().Append($"delete from CrmRealmService where JobId = '{jobId}'");
					var rowCount = db.ExecuteNonQuery(sql.ToString());

					sql.Clear().Append($"delete from CrmRealmJob where JobId = '{jobId}'");
					rowCount = db.ExecuteNonQuery(sql.ToString());
				}
			}
		}
	}
}

The RemoveDeletedJobs runs the same code to remove a Job as found in the RemoveDeletedRecords procedure which handles some other tasks as well.

When run the second time the Job record is found and the code executes as expected?