Azure/azure-spatial-anchors-samples

AlreadyAssociatedWithADifferentStore error, what does it mean ?

Closed this issue · 6 comments

Hi !

I am trying to find why I cannot locate some anchors and I got the AlreadyAssociatedWithADifferentStore a few times. I am working on finding the steps to reproduce the issue currently but i am flying a bit blind here.
Would it be possible to have more information about this specific error code, the description that is in the documentation is not that clear : AlreadyAssociatedWithADifferentStore. What is a Store object ?

Hi @tomkrikorian, we would be happy to help you resolve your issue. Can you please provide some more context on what you are trying to do? For example, how do you go about trying to locate your anchor? Are you using multiple sessions? Are you using multiple watchers? If possible is there some snippet of code you are able to share with us?

Finally, do the samples provided work for you?

Hi @oafolabi-msft,

Some context for our use case :
Our app basically allows anyone to post 3D content tied to a spatial anchor and retrieve the content posted by other users by finding spatial anchors.

We are using coarse relocalization with NearDeviceCriteria to locate anchors. We only have one session and one watcher (since multiple watchers are not possible at the moment).

We start the ASA Session & the Watcher at app launch as follow :

				await _spatialAnchorManager.CreateSessionAsync();
				_locationProvider = new PlatformLocationProvider();
				SensorPermissionHelper.RequestSensorPermissions();
				_locationProvider.Sensors.GeoLocationEnabled = SensorPermissionHelper.HasGeoLocationPermission();
				_locationProvider.Sensors.WifiEnabled = false;
				_locationProvider.Sensors.BluetoothEnabled = false;
				_spatialAnchorManager.Session.LocationProvider = _locationProvider;
				_spatialAnchorManager.Session.Diagnostics.ImagesEnabled = true;
				_spatialAnchorManager.Session.Diagnostics.LogLevel = SessionLogLevel.Warning;
				_spatialAnchorManager.Session.Diagnostics.MaxDiskSizeInMB = 50;
				_spatialAnchorManager.SessionUpdated += OnSessionUpdated;
				_spatialAnchorManager.Error += OnError;
				_spatialAnchorManager.Session.TelemetryEnabled = false;
				await _spatialAnchorManager.StartSessionAsync();
				_anchorLocateCriteria = new AnchorLocateCriteria();
				NearDeviceCriteria nearDeviceCriteria = new NearDeviceCriteria();
				nearDeviceCriteria.DistanceInMeters = 20;
				nearDeviceCriteria.MaxResultCount = 20;
				_anchorLocateCriteria.NearDevice = nearDeviceCriteria;
				_anchorLocateCriteria.Strategy = LocateStrategy.VisualInformation;
				_anchorLocateCriteria.BypassCache = true;
				_anchorLocateCriteria.RequestedCategories = AnchorDataCategory.Spatial;
				await StartWatcher();

After investigation it seems this error actually happens when a user :

  • Creates an anchor :
                                // We stop the watcher because we noticed it would crash the app if we save an anchor and we have a watcher running at the same time.
                                StopWatcher();
				CloudNativeAnchor cloudNativeAnchor = newAnchor.AddComponent<CloudNativeAnchor>();

				if (cloudNativeAnchor.CloudAnchor == null)
				{
					await cloudNativeAnchor.NativeToCloud();
				}

				CloudSpatialAnchor cloudAnchor = cloudNativeAnchor.CloudAnchor;

				while (!_spatialAnchorManager.IsReadyForCreate)
				{
					await UniTask.Delay(330, false, PlayerLoopTiming.Update, cancellationToken);
					if (_sessionUpdatedSubject.Value == SessionUserFeedback.None)
					{
						_readyForCreateProgressSubject.OnNext(_spatialAnchorManager.SessionStatus.ReadyForCreateProgress);
						_cloudAnchorProgressSubject.OnNext(_spatialAnchorManager.SessionStatus.RecommendedForCreateProgress));
					}
				}

				await _spatialAnchorManager.CreateAnchorAsync(cloudAnchor, cancellationToken);

Then if we try to delete that anchor :

CloudSpatialAnchor cloudAnchor = cloudNativeAnchor.CloudAnchor;
await _spatialAnchorManager.Session.DeleteAnchorAsync(cloudSpatialAnchor);

The deletion of the anchor fails and in the logs i see this Error about AlreadyAssociatedWithADifferentStore.

This seems to fix the issue :

CloudSpatialAnchor cloudSpatialAnchor = await _spatialAnchorManager.Session.GetAnchorPropertiesAsync(anchorToRemove.Identifier);
await _spatialAnchorManager.Session.DeleteAnchorAsync(cloudSpatialAnchor);

I still have my issue about not finding some anchors but at least i cannot reproduce the AlreadyAssociatedWithADifferentStore

So basically we cannot use the CloudAnchor of the CloudNativeAnchor to delete an anchor ? Is the Store object mentionned in the error a CloudAnchor Object ?

About the issue of not finding anchors,
We have to stop the watcher when we :

  • Delete an anchor
  • Save an anchor
    And when that operation is done we restart it.
    Could it be that restarting the watcher multiple times create an issue to locate anchors ?

hi @tomkrikorian, thank you for sharing with us a great observation. The store object is an internal (server side) construct that manages operations on (cloud) spatial anchors and is re-created as determined needed.
One can use CloudSpatialAnchor of ClouldNativeAnchor for immediate deletion, as demonstrated in CoarseRelocDemo (here).
However, a more robust way is what you already pointed out:

CloudSpatialAnchor cloudSpatialAnchor = await _spatialAnchorManager.Session.GetAnchorPropertiesAsync(anchorToRemove.Identifier);
await _spatialAnchorManager.Session.DeleteAnchorAsync(cloudSpatialAnchor);

Since the store object is subject to change (e.g. reset/new instance) to handle various conditions as user application goes through many operations, relying on permanent info (Identifier) is more desirable.
This robust way is also demonstrated in NearbyDemo (here). Hope that the info would help.

Regarding the issue of not finding anchors, it's not clear to me if restarting the watcher multiple times would make it harder to locate anchors (assuming observing the same environment data all the time). Could you please elaborate on how to reproduce the issue and if possible, opening another ticket to make it easier for follow up?

CloudSpatialAnchor cloudSpatialAnchor = await _spatialAnchorManager.Session.GetAnchorPropertiesAsync(anchorToRemove.Identifier);
await _spatialAnchorManager.Session.DeleteAnchorAsync(cloudSpatialAnchor);

This Fixed all our issues. We don't have to stop the watcher before deleting an anchor or saving one too. I would suggest you make it clear in your documentation that this is the proper way to do it. I've been using ASA SDK for a long time now and always thought it was fine to use the CloudSpatialAnchor for a CloudNativeAnchor but it seems to cause a lot of issues.

On the anchors not being found, i will create a new ticket when i have more informations about the issue. For now it's only reported by some users and i can't really reproduce on my side. I think it has to do with anchors saved in outdoor environments and not found weeks later, not sure we can do much about it.

It's really great to hear that you've fixed the issues, making use of the API GetAnchorPropertiesAsync.
I also think the documentation needs improvement to help developers avoid running into the error AlreadyAssociatedWithADifferentStore unexpectedly. We have an internal item to track this (#37550221).
Thanks for helping us understand the on-going issue(s) and for the suggestion of needed improvement.

Note - while I closed this item a couple of weeks ago, we are still tracking this (#37550221). as a part of our documentation updates (assigned to @pamistel )