Skip to content

Commit ae0c9ce

Browse files
committed
Enhance identity assignment logic and update tests for duplicate handling
1 parent b07436d commit ae0c9ce

2 files changed

Lines changed: 67 additions & 22 deletions

File tree

src/AXSharp.connectors/src/AXSharp.Connector/Identity/TwinIdentityProvider.cs

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ internal async Task<IEnumerable<OnlinerULInt>> ReadIdentitiesAsync()
206206
/// </summary>
207207
/// <param name="identities">Identities</param>
208208
/// <param name="identityProvider">Identity creator.</param>
209-
/// <returns></returns>
209+
/// <returns>Assigned identities.</returns>
210210
public IEnumerable<OnlinerULInt> AssignIdentities(IEnumerable<OnlinerULInt> identities, Func<OnlinerULInt, ulong> identityProvider = null)
211211
{
212212
// If no identity provider is given, use default one based on hash code of the symbol.
@@ -234,46 +234,88 @@ public async Task WriteIdentities(IEnumerable<OnlinerULInt> identitiesToWrite)
234234
}
235235

236236
/// <summary>
237-
/// Refreshes and sorts identities.
237+
/// Constructs identities by assigning them locally and writing to PLC, then sorts them by their assigned values.
238238
/// </summary>
239-
public async Task ConstructIdentitiesAsync(Func<OnlinerULInt, ulong> identityProvider = null)
239+
/// <param name="identityProvider">Function to provide identity values.</param>
240+
/// <param name="failOnDuplicate">Indicates whether to fail on duplicate identities.</param>
241+
/// <returns></returns>
242+
public async Task ConstructIdentitiesAsync(Func<OnlinerULInt, ulong> identityProvider = null, bool failOnDuplicate = true)
240243
{
241-
await WriteIdentities(AssignIdentities(_identitiesTags, identityProvider));
242-
await SortIdentitiesAsync();
244+
await WriteIdentities(AssignIdentities(_identitiesTags, identityProvider));
245+
await SortIdentitiesAsync(failOnDuplicate);
243246
}
244247

245248
/// <summary>
246-
/// Sorts identities.
249+
/// Sorts identities using the locally assigned Cyclic values, without reading back from PLC.
247250
/// </summary>
248-
internal async Task SortIdentitiesAsync()
251+
internal async Task SortIdentitiesAsync(bool failOnDuplicate = true)
249252
{
250-
await Task.Run(async () =>
253+
_connector?.Logger.Information("Sorting identities from assigned values...");
254+
_sortedIdentities.Clear();
255+
foreach (var identity in _identities)
251256
{
252-
_connector?.Logger.Information("Sorting identities...");
253-
if (_connector != null)
257+
var key = identity.Key.Cyclic;
258+
if (!_sortedIdentities.ContainsKey(key) && key != 0)
254259
{
255-
await _connector?.ReadBatchAsync(_identities.Select(p => p.Key), eAccessPriority.High);
260+
_sortedIdentities.Add(key, identity.Value);
256261
}
257-
_sortedIdentities.Clear();
258-
foreach (var identity in _identities)
262+
else
259263
{
260-
var key = identity.Key.LastValue;
261-
if (!_sortedIdentities.ContainsKey(key))
262-
{
263-
_sortedIdentities.Add(key, identity.Value);
264-
}
265-
else
264+
if (failOnDuplicate)
266265
{
267266
throw new DuplicateIdentityException("There is a duplicate identity: " +
268-
$"{identity.Value.Symbol} : {key}." +
267+
$"'{identity.Value.Symbol} : {key}.'" +
268+
$" and '{_sortedIdentities[key].Symbol} : {key}.'" +
269+
$" share the same identity value." +
269270
$"The algorithm for assigning identities needs to be adjusted." +
270271
$"Use an algorithm that guarantees unique identities and is less prone to collisions.");
271272
}
273+
else
274+
{
275+
_connector?.Logger.Warning($"Duplicate identity detected: '{identity.Value.Symbol} : {key}' and '{_sortedIdentities[key].Symbol} : {key}' share the same identity value. " +
276+
$"This entry will be ignored."+
277+
$"The algorithm for assigning identities needs to be adjusted." +
278+
$"Use an algorithm that guarantees unique identities and is less prone to collisions." +
279+
$"Ignoring this warning may lead to unexpected behavior in those parts of the system that rely on unique identities.");
280+
}
272281
}
282+
}
273283

274-
_connector?.Logger.Information("Sorting identities done.");
275-
});
284+
_connector?.Logger.Information("Sorting identities done.");
276285
}
286+
287+
// /// <summary>
288+
// /// Sorts identities by reading values from PLC.
289+
// /// </summary>
290+
// internal async Task SortIdentitiesAsync()
291+
// {
292+
// await Task.Run(async () =>
293+
// {
294+
// _connector?.Logger.Information("Sorting identities...");
295+
// if (_connector != null)
296+
// {
297+
// await _connector?.ReadBatchAsync(_identities.Select(p => p.Key), eAccessPriority.High);
298+
// }
299+
// _sortedIdentities.Clear();
300+
// foreach (var identity in _identities)
301+
// {
302+
// var key = identity.Key.LastValue;
303+
// if (!_sortedIdentities.ContainsKey(key))
304+
// {
305+
// _sortedIdentities.Add(key, identity.Value);
306+
// }
307+
// else
308+
// {
309+
// throw new DuplicateIdentityException("There is a duplicate identity: " +
310+
// $"{identity.Value.Symbol} : {key}." +
311+
// $"The algorithm for assigning identities needs to be adjusted." +
312+
// $"Use an algorithm that guarantees unique identities and is less prone to collisions.");
313+
// }
314+
// }
315+
316+
// _connector?.Logger.Information("Sorting identities done.");
317+
// });
318+
// }
277319
}
278320

279321
/// <summary>

src/AXSharp.connectors/tests/AXSharp.ConnectorTests/AXSharp.ConnectorTests/Identity/TwinIdentityProviderTests.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,16 +220,19 @@ public async void CanCallSortIdentities()
220220

221221
var identityVar_2 = Substitute.For<OnlinerULInt, IOnline<ulong>>();
222222
identityVar_2.LastValue.Returns(2ul);
223+
identityVar_2.Cyclic.Returns(2ul);
223224
var obj2 = Substitute.For<ITwinIdentity>();
224225
obj2.Identity.Returns(identityVar_2);
225226

226227
var identityVar_1 = Substitute.For<OnlinerULInt, IOnline<ulong>>();
227228
var obj1 = Substitute.For<ITwinIdentity>();
228229
obj1.Identity.Returns(identityVar_1);
229230
identityVar_1.LastValue.Returns(1ul);
231+
identityVar_1.Cyclic.Returns(1ul);
230232

231233
var identityVar_3 = Substitute.For<OnlinerULInt, IOnline<ulong>>();
232234
identityVar_3.LastValue.Returns(3ul);
235+
identityVar_3.Cyclic.Returns(3ul);
233236
var obj3 = Substitute.For<ITwinIdentity>();
234237
obj3.Identity.Returns(identityVar_3);
235238

0 commit comments

Comments
 (0)