PI WEBAPI limit for batch request

Hi All! Good Morning!

 

The system was developed in C#. The system tries to retrieve the event frames for all elements on the same level of the hierarchy. There are 72 elements and 277 event frames are expected on this 3 months search period.

 

The system throws an error when using batch to get all elements and then get all event frames:

 

System.AggregateException
  HResult=0x80131500
  Message=One or more errors occurred. (A task was canceled.)
  Source=System.Private.CoreLib
  StackTrace:
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at PILibrary.Controllers.PILibraryController.ReadExperimentsRuns2(String siteName, String bioreactorClass, DateTime periodStartDate, DateTime periodEndDate) in D:\TQS\repos\pilibrary\PILibrary\Controllers\PISDKInterfaceController.cs:line 2444

Inner Exception 1:
TaskCanceledException: A task was canceled.

 

When limiting the query to first result the system returns correct information with no error.

 

An alternative method was created to query all elements, create a list of webIDs an than perform a for loop to get event frames for each event frame, but this method is taking up to 17 minutes to finish.

 

When using parallel.for or paralle.foreach the system towns the following error:

 

System.AggregateException
  HResult=0x80131500
  Message=One or more errors occurred. (A task was canceled.)
  Source=System.Private.CoreLib
  StackTrace:
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at PILibrary.Controllers.PILibraryController.<>c__DisplayClass56_1.<ReadExperimentsRuns>b__0(Int32 l) in D:\TQS\repos\pilibrary\PILibrary\Controllers\PISDKInterfaceController.cs:line 2145
   at System.Threading.Tasks.Parallel.<>c__DisplayClass19_0`1.<ForWorker>b__1(RangeWorker& currentWorker, Int32 timeout, Boolean& replicationDelegateYieldedBeforeCompletion)

Inner Exception 1:
TaskCanceledException: A task was canceled.

Any suggestions?

Thanks in advance

Parents
  • The Batch Controller represents a great option to avoid network latency between the client and the PI Web API host. This latency is added each time a request is send and each time a response is received. Using the Batch Controller is however not a guarantee of most efficient data retrieval. Batched requests are executed one-by-one on the PI Web API host and if the PI Web API host is remote to the AF Server and / or the PI Data Archive and eventually other resources, there could still be a lot of back-and-forth communication and because HttpClient communication is asynchronous it usually has a timeout which makes the client cancel the request when the timeout has elapsed. Increasing the client timeout is one option to address the situation.

    My recommendation would however be to use an action which I expect to be more efficient because it uses OSIsoft.AF.Search: GetEventFramesQuery

    What we don't know is how big the expected result-set is. Yes, it is possible to request Event Frames for a period of 3 months but what if there is let's say a million Event Frames? Would that mean to display a table with 1 million records in it? If so, is there an expectation this table fits on a single page? Are we expecting a human being being able to digest this amount of records or are we paging the results for the user?

    GetEventFramesQuery uses the paging approach and has a default page size of 1000 which appears .. reasonably enough for general purpose.

  • Hi Gregor! Thanks for your answer. We expect to have around 277 Event Frames in this 3 months period, but we need to make sure that we are looking for the event frames that are children of those specific 72 elements. The 72 elements are all children of one specific parent element on the root.

     

    -ParentElement01

    -ChildElementToGetEventFrame01_01

    -ChildElementToGetEventFrame01_02

    -ChildElementToGetEventFrame01_03

    ....

    -ParentElement02

    -ChildElementToGetEventFrame02_01

    -ChildElementToGetEventFrame02_02

    -ChildElementToGetEventFrame02_03

    ....

     

    There are several branches on the treeview and we need to search t=for all event frames on a given branch.

     

    I couldn't realize how to search for all event frame for all children element in a specific branch.

    I couldn't find a way to search for event frames of a specific list of elements using GetEventFramesQuery .

     

    My current c# batch query that is throwing the first error (task was canceled) is the following:

    obj = new
                    {
                        assetdatabases = new
                        {
                            Method = "GET",
                            Resource = "https://" + _PIWebAPIServer + "/piwebapi/assetdatabases?path=" + _AFServer + _AFDatabase + "&selectedFields=Name;WebID;Path",
                        },
                        element = new
                        {
                            Method = "GET",
                            Resource = "https://" + _PIWebAPIServer + "/piwebapi/elements?path=" + ElementPath + "&selectedFields=Name;WebId;Path;CategoryNames",
                            ParentIds = new string[] { "assetdatabases" },
                            Parameters = new string[] { "$.assetdatabases.Content.WebId" }
                        },
                        childelements = new
                        {
                            Method = "GET",
                            Resource = "https://" + _PIWebAPIServer + "/piwebapi/elements/{0}/elements?nameFilter=" + ParentElementName + "&selectedFields=Items.Name;Items.WebId;Items.Path;Items.CategoryNames",
                            ParentIds = new string[] { "element" },
                            Parameters = new string[] { "$.element.Content.WebId" }
                        },
                        grandchildelements = new
                        {
                            Method = "GET",
                            RequestTemplate = new
                            {
                                Resource = "https://" + _PIWebAPIServer + "/piwebapi/elements/{0}/elements?selectedFields=Items.Name;Items.WebId;Items.Path;Items.CategoryNames;Items.Template"
                            },
                            ParentIds = new string[] { "childelements" },
                            Parameters = new string[] { "$.childelements.Content.Items[*].WebId" }
                        },                    
                        eventframes = new
                        {
                            Headers = new Dictionary<string, string>() { { "Cache-Control", "no-cache" } },
                            Method = "GET",
                            RequestTemplate = new
                            {
                                Resource = "https://" + _PIWebAPIServer + "/piwebapi/elements/{0}/eventframes?startTime=" + periodStartDate.ToString("o") + "&endTime=" + periodEndDate.ToString("o") + "&templateName=" + _RunEventFrameTemplateName + "" + "&selectedFields=Items.Name;Items.WebId;Items.Path;Items.CategoryNames;Items.Template;Items.StartTime;Items.EndTime;Items.Name;Items.Value;Items.Links.Parent"
                            },
                            ParentIds = new string[] { "grandchildelements" },
                            Parameters = new string[] { "$.grandchildelements.Content.Items[*].Content.Items[*].WebId" }
                        }
    }

    Thanks in advance!

     

     

  • Hello ​ ,

    I beg your pardon but my impression is that you didn't even try GetEventFramesQuery and I am hence renewing my suggestion plus adding the hint to read through Search Query Syntax (Core Services) and based on your purpose add another pointer: Search Modes

    As far as your code goes, I understand you are passing the name of the AFDatabase and the root level AFElement, searching for the direct children and for the grandchildren and loading EventFrames but only for the grandchildren. My idea would be filtering by things like EventFrame Template but for sure you can also search for all but there is also the option to refer the ElementTemplate of grandchildren if those all share the same or a set of templates.

     

  • Hi Gregor. The system wasn't prepared to filter by element template or event frame template. for our proposes It is better to filter by element template. Even thought we can have multiple derived templates within she same hierarchy and we would need to search for Element template with an wildcard. I think that is not possible to insert an wildcard for Element template name, am I correct?

    eventframes = new
                        {
                            Headers = new Dictionary<string, string>() { { "Cache-Control", "no-cache" } },
                            Method = "GET",
                            Resource = "https://" + _PIWebAPIServer + "/piwebapi/eventframes/search?databaseWebId={0}&query=Start:>='" + periodStartDate.ToLocalTime().ToString("MM/dd/yyyy hh:mm:ss tt") + "' End:<='" + periodEndDate.ToLocalTime().ToString("MM/dd/yyyy hh:mm:ss tt") + "' ElementReferenceTemplate:'" + bioreactorClass.Replace("Bioreactors", "Base").Replace("(", "").Replace(")", "") + " Template *" + siteName + "' Template:'" + _RunEventFrameTemplateName + "'" + "&selectedFields=Items.Name;Items.WebId;Items.Path;Items.CategoryNames;Items.Template;Items.StartTime;Items.EndTime;Items.Name;Items.Value;Items.Links.Parent",
                            ParentIds = new string[] { "assetdatabases" },
                            Parameters = new string[] { "$.assetdatabases.Content.WebId" }
                        },

    I am getting this error when adding the "*" wildcard on it.

    PILibrary.Exceptions.CustomException: 'The object for 'Base 2L CC Template *SSF SSCC' in search criteria 'ElementReferenceTemplate:"Base 2L CC Template *SSF SSCC"' was not found.'

    It would be perfect if we could filter by Element Category, is this possible? I couldn't find a way looking at the documentation.

    Thanks a lot for your help so far.

Reply
  • Hi Gregor. The system wasn't prepared to filter by element template or event frame template. for our proposes It is better to filter by element template. Even thought we can have multiple derived templates within she same hierarchy and we would need to search for Element template with an wildcard. I think that is not possible to insert an wildcard for Element template name, am I correct?

    eventframes = new
                        {
                            Headers = new Dictionary<string, string>() { { "Cache-Control", "no-cache" } },
                            Method = "GET",
                            Resource = "https://" + _PIWebAPIServer + "/piwebapi/eventframes/search?databaseWebId={0}&query=Start:>='" + periodStartDate.ToLocalTime().ToString("MM/dd/yyyy hh:mm:ss tt") + "' End:<='" + periodEndDate.ToLocalTime().ToString("MM/dd/yyyy hh:mm:ss tt") + "' ElementReferenceTemplate:'" + bioreactorClass.Replace("Bioreactors", "Base").Replace("(", "").Replace(")", "") + " Template *" + siteName + "' Template:'" + _RunEventFrameTemplateName + "'" + "&selectedFields=Items.Name;Items.WebId;Items.Path;Items.CategoryNames;Items.Template;Items.StartTime;Items.EndTime;Items.Name;Items.Value;Items.Links.Parent",
                            ParentIds = new string[] { "assetdatabases" },
                            Parameters = new string[] { "$.assetdatabases.Content.WebId" }
                        },

    I am getting this error when adding the "*" wildcard on it.

    PILibrary.Exceptions.CustomException: 'The object for 'Base 2L CC Template *SSF SSCC' in search criteria 'ElementReferenceTemplate:"Base 2L CC Template *SSF SSCC"' was not found.'

    It would be perfect if we could filter by Element Category, is this possible? I couldn't find a way looking at the documentation.

    Thanks a lot for your help so far.

Children
No Data