예제 #1
0
        /// <summary>
        /// Makes a Query where the expected Result is a SparqlResultSet ie. SELECT and ASK Queries
        /// </summary>
        /// <param name="handler">Results Handler to process the results</param>
        /// <param name="sparqlQuery">SPARQL Query String</param>
        /// <exception cref="RdfQueryException">Thrown if any of the requests to the endpoints fail</exception>
        /// <exception cref="RdfQueryTimeoutException">Thrown if not all the requests complete within the set timeout</exception>
        public override void QueryWithResultSet(ISparqlResultsHandler handler, string sparqlQuery)
        {
            //If no endpoints do nothing
            if (this._endpoints.Count == 0)
            {
                return;
            }

            //Fire off all the Asychronous Requests
            List <AsyncQueryWithResultSet> asyncCalls   = new List <AsyncQueryWithResultSet>();
            List <IAsyncResult>            asyncResults = new List <IAsyncResult>();
            int count = 0;

            foreach (SparqlRemoteEndpoint endpoint in this._endpoints)
            {
                //Limit the number of simultaneous requests we make to the user defined level (default 4)
                //We do this limiting check before trying to issue a request so that when the last request
                //is issued we'll always drop out of the loop and move onto our WaitAll()
                while (count >= this._maxSimultaneousRequests)
                {
                    //First check that the count of active requests is accurate
                    int active = asyncResults.Count(r => !r.IsCompleted);
                    if (active < count)
                    {
                        //Some of the requests have already completed so we don't need to wait
                        count = active;
                        break;
                    }
                    else if (active > count)
                    {
                        //There are more active requests then we thought
                        count = active;
                    }

                    //While the number of requests is at/above the maximum we'll wait for any of the requests to finish
                    //Then we can decrement the count and if this drops back below our maximum then we'll go back into the
                    //main loop and fire off our next request
                    WaitHandle.WaitAny(asyncResults.Select(r => r.AsyncWaitHandle).ToArray());
                    count--;
                }

                //Make an asynchronous query to the next endpoint
                AsyncQueryWithResultSet d = new AsyncQueryWithResultSet(endpoint.QueryWithResultSet);
                asyncCalls.Add(d);
                IAsyncResult asyncResult = d.BeginInvoke(sparqlQuery, null, null);
                asyncResults.Add(asyncResult);
                count++;
            }

            //Wait for all our requests to finish
            int waitTimeout = (base.Timeout > 0) ? base.Timeout : System.Threading.Timeout.Infinite;

            WaitHandle.WaitAll(asyncResults.Select(r => r.AsyncWaitHandle).ToArray(), waitTimeout);

            //Check for and handle timeouts
            if (!this._ignoreFailedRequests && !asyncResults.All(r => r.IsCompleted))
            {
                for (int i = 0; i < asyncCalls.Count; i++)
                {
                    try
                    {
                        asyncCalls[i].EndInvoke(asyncResults[i]);
                    }
                    catch
                    {
                        //Exceptions don't matter as we're just ensuring all the EndInvoke() calls are made
                    }
                }
                throw new RdfQueryTimeoutException("Federated Querying failed due to one/more endpoints failing to return results within the Timeout specified which is currently " + (base.Timeout / 1000) + " seconds");
            }

            //Now merge all the results together
            HashSet <String> varsSeen = new HashSet <string>();
            bool             cont     = true;

            for (int i = 0; i < asyncCalls.Count; i++)
            {
                //Retrieve the result for this call
                AsyncQueryWithResultSet call = asyncCalls[i];
                SparqlResultSet         partialResult;
                try
                {
                    partialResult = call.EndInvoke(asyncResults[i]);
                }
                catch (Exception ex)
                {
                    if (!this._ignoreFailedRequests)
                    {
                        //Clean up in the event of an error
                        for (int j = i + 1; j < asyncCalls.Count; j++)
                        {
                            try
                            {
                                asyncCalls[j].EndInvoke(asyncResults[j]);
                            }
                            catch
                            {
                                //Exceptions don't matter as we're just ensuring all the EndInvoke() calls are made
                            }
                        }

                        //If a single request fails then the entire query fails
                        throw new RdfQueryException("Federated Querying failed due to the query against the endpoint '" + this._endpoints[i].Uri.ToString() + "' failing", ex);
                    }
                    else
                    {
                        //If we're ignoring failed requests we continue here
                        continue;
                    }
                }

                //Merge the result into the final results
                //If the handler has previously told us to stop we skip this step
                if (cont)
                {
                    foreach (String variable in partialResult.Variables)
                    {
                        cont = handler.HandleVariable(variable);
                        //Stop if handler tells us to
                        if (!cont)
                        {
                            break;
                        }
                    }

                    if (cont)
                    {
                        foreach (SparqlResult result in partialResult.Results)
                        {
                            cont = handler.HandleResult(result);
                            //Stop if handler tells us to
                            if (!cont)
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Makes a Query where the expected Result is a SparqlResultSet ie. SELECT and ASK Queries
        /// </summary>
        /// <param name="handler">Results Handler to process the results</param>
        /// <param name="sparqlQuery">SPARQL Query String</param>
        /// <exception cref="RdfQueryException">Thrown if any of the requests to the endpoints fail</exception>
        /// <exception cref="RdfQueryTimeoutException">Thrown if not all the requests complete within the set timeout</exception>
        public override void QueryWithResultSet(ISparqlResultsHandler handler, string sparqlQuery)
        {
            //If no endpoints do nothing
            if (this._endpoints.Count == 0) return;

            //Fire off all the Asychronous Requests
            List<AsyncQueryWithResultSet> asyncCalls = new List<AsyncQueryWithResultSet>();
            List<IAsyncResult> asyncResults = new List<IAsyncResult>();
            int count = 0;
            foreach (SparqlRemoteEndpoint endpoint in this._endpoints)
            {
                //Limit the number of simultaneous requests we make to the user defined level (default 4)
                //We do this limiting check before trying to issue a request so that when the last request
                //is issued we'll always drop out of the loop and move onto our WaitAll()
                while (count >= this._maxSimultaneousRequests)
                {
                    //First check that the count of active requests is accurate
                    int active = asyncResults.Count(r => !r.IsCompleted);
                    if (active < count)
                    {
                        //Some of the requests have already completed so we don't need to wait
                        count = active;
                        break;
                    }
                    else if (active > count)
                    {
                        //There are more active requests then we thought
                        count = active;
                    }

                    //While the number of requests is at/above the maximum we'll wait for any of the requests to finish
                    //Then we can decrement the count and if this drops back below our maximum then we'll go back into the
                    //main loop and fire off our next request
                    WaitHandle.WaitAny(asyncResults.Select(r => r.AsyncWaitHandle).ToArray());
                    count--;
                }

                //Make an asynchronous query to the next endpoint
                AsyncQueryWithResultSet d = new AsyncQueryWithResultSet(endpoint.QueryWithResultSet);
                asyncCalls.Add(d);
                IAsyncResult asyncResult = d.BeginInvoke(sparqlQuery, null, null);
                asyncResults.Add(asyncResult);
                count++;
            }

            //Wait for all our requests to finish
            int waitTimeout = (base.Timeout > 0) ? base.Timeout : System.Threading.Timeout.Infinite;
            WaitHandle.WaitAll(asyncResults.Select(r => r.AsyncWaitHandle).ToArray(), waitTimeout);

            //Check for and handle timeouts
            if (!this._ignoreFailedRequests && !asyncResults.All(r => r.IsCompleted))
            {
                for (int i = 0; i < asyncCalls.Count; i++)
                {
                    try
                    {
                        asyncCalls[i].EndInvoke(asyncResults[i]);
                    }
                    catch
                    {
                        //Exceptions don't matter as we're just ensuring all the EndInvoke() calls are made
                    }
                }
                throw new RdfQueryTimeoutException("Federated Querying failed due to one/more endpoints failing to return results within the Timeout specified which is currently " + (base.Timeout / 1000) + " seconds");
            }

            //Now merge all the results together
            HashSet<String> varsSeen = new HashSet<string>();
            bool cont = true;
            for (int i = 0; i < asyncCalls.Count; i++)
            {
                //Retrieve the result for this call
                AsyncQueryWithResultSet call = asyncCalls[i];
                SparqlResultSet partialResult;
                try
                {
                    partialResult = call.EndInvoke(asyncResults[i]);
                }
                catch (Exception ex)
                {
                    if (!this._ignoreFailedRequests)
                    {
                        //Clean up in the event of an error
                        for (int j = i + 1; j < asyncCalls.Count; j++)
                        {
                            try
                            {
                                asyncCalls[j].EndInvoke(asyncResults[j]);
                            }
                            catch
                            {
                                //Exceptions don't matter as we're just ensuring all the EndInvoke() calls are made
                            }
                        }

                        //If a single request fails then the entire query fails
                        throw new RdfQueryException("Federated Querying failed due to the query against the endpoint '" + this._endpoints[i].Uri.ToString() + "' failing", ex);
                    }
                    else
                    {
                        //If we're ignoring failed requests we continue here
                        continue;
                    }
                }

                //Merge the result into the final results
                //If the handler has previously told us to stop we skip this step
                if (cont)
                {
                    foreach (String variable in partialResult.Variables)
                    {
                        cont = handler.HandleVariable(variable);
                        //Stop if handler tells us to
                        if (!cont) break;
                    }

                    if (cont)
                    {
                        foreach (SparqlResult result in partialResult.Results)
                        {
                            cont = handler.HandleResult(result);
                            //Stop if handler tells us to
                            if (!cont) break;
                        }
                    }
                }
            }
        }