예제 #1
0
 /// <summary>
 ///     No throw. Returns null or changed clientObjs (not null, but possibly zero-lenghth).
 /// </summary>
 public object[]? PollChanges()
 {
     if (DataGrpcList is null || DataGrpcList.Disposed)
     {
         return(null);
     }
     try
     {
         var changedClientObjs = new List <object>();
         ClientElementValueListItem[] changedClientElementValueListItems = DataGrpcList.PollElementValuesChanges();
         foreach (ClientElementValueListItem dataGrpcElementValueListItem in changedClientElementValueListItems)
         {
             var o = dataGrpcElementValueListItem.Obj as DataGrpcListItemWrapper;
             if (o is null)
             {
                 throw new InvalidOperationException();
             }
             foreach (var modelItem in o.ClientObjectInfosCollection)
             {
                 if (modelItem.ClientObj is not null)
                 {
                     changedClientObjs.Add(modelItem.ClientObj);
                 }
             }
         }
         return(changedClientObjs.ToArray());
     }
     catch
     {
     }
     return(null);
 }
예제 #2
0
        /// <summary>
        ///     Returns whether connection errors occur.
        /// </summary>
        /// <returns></returns>
        protected bool SubscribeInitial()
        {
            bool connectionError = false;

            foreach (ClientObjectInfo clientObjectInfo in _clientObjectInfosDictionary.Values)
            {
                if (clientObjectInfo.DataGrpcListItemWrapper is null)
                {
                    var elementId = clientObjectInfo.ElementId;
                    DataGrpcListItemWrapper?dataGrpcListItemWrapper;
                    if (!_dataGrpcListItemWrappersDictionary.TryGetValue(elementId, out dataGrpcListItemWrapper))
                    {
                        dataGrpcListItemWrapper = new DataGrpcListItemWrapper();
                        _dataGrpcListItemWrappersDictionary.Add(elementId, dataGrpcListItemWrapper);
                    }
                    clientObjectInfo.ForceNotifyClientObj    = true;
                    clientObjectInfo.DataGrpcListItemWrapper = dataGrpcListItemWrapper;
                    dataGrpcListItemWrapper.ClientObjectInfosCollection.Add(clientObjectInfo);
                }
            }

            var dataGrpcListItemWrappersToAdd = new List <DataGrpcListItemWrapper>();

            foreach (var kvp in _dataGrpcListItemWrappersDictionary)
            {
                DataGrpcListItemWrapper dataGrpcListItemWrapper = kvp.Value;
                if (dataGrpcListItemWrapper.DataGrpcListItem is null && !dataGrpcListItemWrapper.ItemDoesNotExist)
                {
                    dataGrpcListItemWrappersToAdd.Add(dataGrpcListItemWrapper);
                    TDataGrpcListItem?dataGrpcListItem = null;
                    if (DataGrpcList is not null && !DataGrpcList.Disposed)
                    {
                        try
                        {
                            dataGrpcListItem = DataGrpcList.PrepareAddItem(kvp.Key);
                        }
                        catch
                        {
                            connectionError = true;
                        }
                    }
예제 #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="clientObj"></param>
        /// <param name="valueStatusTimestamp"></param>
        public void Write(object clientObj, ValueStatusTimestamp valueStatusTimestamp)
        {
            if (DataGrpcList is null || DataGrpcList.Disposed)
            {
                return;
            }

            ClientObjectInfo?modelItem;

            if (!ModelItemsDictionary.TryGetValue(clientObj, out modelItem))
            {
                return;
            }

            if (modelItem.DataGrpcListItemWrapper is null || modelItem.DataGrpcListItemWrapper.DataGrpcListItem is null || modelItem.DataGrpcListItemWrapper.DataGrpcListItem.StatusCode != StatusCode.OK)
            {
                return;
            }

            ClientElementValueListItem dataGrpcElementValueListItem = modelItem.DataGrpcListItemWrapper.DataGrpcListItem;

            try
            {
                dataGrpcElementValueListItem.PrepareForWrite(valueStatusTimestamp);

                try
                {
                    DataGrpcList.CommitWriteElementValueListItems();
                }
                catch
                {
                }
            }
            catch (Exception ex)
            {
                Logger.LogWarning(ex, "DataGrpcList.CommitWriteElementValueListItems() exception");
            }
        }
예제 #4
0
        /// <summary>
        ///     Creates List, adds/removes items.
        ///     No throw.
        /// </summary>
        /// <param name="clientConnectionManager"></param>
        /// <param name="сallbackDispatcher"></param>
        /// <param name="elementValuesCallbackEventHandler"></param>
        /// <param name="callbackIsEnabled"></param>
        /// <param name="ct"></param>
        public void Subscribe(ClientConnectionManager clientConnectionManager, IDispatcher?сallbackDispatcher,
                              ElementValuesCallbackEventHandler elementValuesCallbackEventHandler, bool callbackIsEnabled, CancellationToken ct)
        {
            try
            {
                if (ct.IsCancellationRequested)
                {
                    return;
                }
                if (!DataGrpcItemsMustBeAddedOrRemoved)
                {
                    return;
                }

                bool firstTimeDataConnection = (DataGrpcList is null);

                if (firstTimeDataConnection)
                {
                    try
                    {
                        if (clientConnectionManager.ConnectionExists)
                        {
                            DataGrpcList = clientConnectionManager.NewElementValueList(null);
                        }
                    }
                    catch (Exception)
                    {
                    }
                }

                bool connectionError = SubscribeInitial();

                try
                {
                    if (!connectionError && DataGrpcList is not null && !DataGrpcList.Disposed)
                    {
                        if (firstTimeDataConnection)
                        {
                            DataGrpcList.ElementValuesCallback +=
                                (ClientElementValueList dataList, ClientElementValueListItem[] items,
                                 ValueStatusTimestamp[] values) =>
                            {
                                var changedClientObjs = new List <object>(items.Length);
                                var changedValues     = new List <ValueStatusTimestamp>(items.Length);
                                int i = 0;
                                foreach (ClientElementValueListItem dataGrpcElementValueListItem in items)
                                {
                                    var o = dataGrpcElementValueListItem.Obj as DataGrpcListItemWrapper;
                                    if (o is null)
                                    {
                                        throw new InvalidOperationException();
                                    }
                                    foreach (var modelItem in o.ClientObjectInfosCollection)
                                    {
                                        modelItem.ForceNotifyClientObj = false;
                                        if (modelItem.ClientObj is not null)
                                        {
                                            changedClientObjs.Add(modelItem.ClientObj);
                                            changedValues.Add(values[i]);
                                        }
                                    }
                                    i++;
                                }
                                if (ct.IsCancellationRequested)
                                {
                                    return;
                                }
                                Logger.LogDebug("DataGrpcList.ElementValuesCallback");
                                if (сallbackDispatcher is not null)
                                {
                                    try
                                    {
                                        сallbackDispatcher.BeginInvoke(ct =>
                                        {
                                            Logger.LogDebug("DataGrpcList.ElementValuesCallback dispatched");
                                            elementValuesCallbackEventHandler(changedClientObjs.ToArray(), changedValues.ToArray());
                                        });
                                    }
                                    catch (Exception)
                                    {
                                    }
                                }
                            };
                            if (callbackIsEnabled)
                            {
                                DataGrpcList.EnableListCallback(true);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogWarning(ex, "ClientElementValueListItemsManager.Subscribe exception");
                    connectionError = true;
                }

                {
                    var utcNow            = DateTime.UtcNow;
                    var changedClientObjs = new List <object>();
                    var changedValues     = new List <ValueStatusTimestamp>();
                    foreach (DataGrpcListItemWrapper dataGrpcListItemWrapper in DataGrpcListItemWrappersDictionary.Values)
                    {
                        foreach (var modelItem in dataGrpcListItemWrapper.ClientObjectInfosCollection)
                        {
                            if (modelItem.ForceNotifyClientObj)
                            {
                                modelItem.ForceNotifyClientObj = false;
                                if (modelItem.ClientObj is not null)
                                {
                                    if (dataGrpcListItemWrapper.ItemDoesNotExist)
                                    {
                                        changedClientObjs.Add(modelItem.ClientObj);
                                        changedValues.Add(new ValueStatusTimestamp {
                                            ValueStatusCode = ValueStatusCode.ItemDoesNotExist
                                        });
                                    }
                                    else if (dataGrpcListItemWrapper.DataGrpcListItem is not null)
                                    {
                                        changedClientObjs.Add(modelItem.ClientObj);
                                        changedValues.Add(dataGrpcListItemWrapper.DataGrpcListItem.ValueStatusTimestamp);
                                    }
                                    else
                                    {
                                        changedClientObjs.Add(modelItem.ClientObj);
                                        changedValues.Add(new ValueStatusTimestamp(new Any(), ValueStatusCode.Unknown, utcNow));
                                    }
                                }
                            }
                        }
                    }
                    if (changedClientObjs.Count > 0)
                    {
                        if (ct.IsCancellationRequested)
                        {
                            return;
                        }
                        if (сallbackDispatcher is not null)
                        {
                            try
                            {
                                сallbackDispatcher.BeginInvoke(ct =>
                                                               elementValuesCallbackEventHandler(changedClientObjs.ToArray(), changedValues.ToArray()));
                            }
                            catch (Exception)
                            {
                            }
                        }
                    }
                }

                if (!connectionError)
                {
                    DataGrpcItemsMustBeAddedOrRemoved = false;
                }
            }
            finally
            {
                SubscribeFinal();
            }
        }
예제 #5
0
        /// <summary>
        ///     Returns clientObjs whose write failed.
        ///     If connection error, no throw and returns all clientObjs.
        /// </summary>
        /// <param name="clientObjs"></param>
        /// <param name="valueStatusTimestamps"></param>
        /// <returns></returns>
        public object[] Write(object[] clientObjs, ValueStatusTimestamp[] valueStatusTimestamps)
        {
            if (DataGrpcList is null || DataGrpcList.Disposed)
            {
                return(clientObjs);
            }

            int i      = -1;
            var result = new List <object>();

            foreach (var clientObj in clientObjs)
            {
                i++;

                ClientObjectInfo?modelItem;
                if (!ModelItemsDictionary.TryGetValue(clientObj, out modelItem))
                {
                    result.Add(clientObj);
                    continue;
                }

                if (modelItem.DataGrpcListItemWrapper is null ||
                    modelItem.DataGrpcListItemWrapper.DataGrpcListItem is null ||
                    modelItem.DataGrpcListItemWrapper.DataGrpcListItem.StatusCode != StatusCode.OK)
                {
                    result.Add(clientObj);
                    continue;
                }
                ClientElementValueListItem dataGrpcElementValueListItem = modelItem.DataGrpcListItemWrapper.DataGrpcListItem;
                dataGrpcElementValueListItem.PrepareForWrite(valueStatusTimestamps[i]);
            }

            IEnumerable <ClientElementValueListItem> failedItems;

            try
            {
                failedItems = DataGrpcList.CommitWriteElementValueListItems();
            }
            catch
            {
                return(clientObjs);
            }

            foreach (var dataGrpcElementValueListItem in failedItems)
            {
                var o = dataGrpcElementValueListItem.Obj as DataGrpcListItemWrapper;
                if (o is null)
                {
                    throw new InvalidOperationException();
                }
                foreach (var modelItem in o.ClientObjectInfosCollection)
                {
                    if (modelItem.ClientObj is not null)
                    {
                        result.Add(modelItem.ClientObj);
                    }
                }
            }

            return(result.ToArray());
        }