예제 #1
0
        public RserveConnection GetConnection(RserveParameter rserveParams)
        {
            Interlocked.Increment(ref poolcounter);
            int poolnodeindex = poolcounter % (rserveParams.PoolNodes.Count);

            PoolNode node = rserveParams.PoolNodes.ElementAt(poolnodeindex);

            var hash = $"{node.rserveParameter.GetHashCode().ToString()}-{node.getNextConnectionNumber().ToString()}";

            logger.Info($"Connecting to node {poolnodeindex} with hash: {hash}");
            RserveConnection conn = null;



            if (rserveConns.ContainsKey(hash))
            {
                rserveConns.TryGetValue(hash, out conn);
                var dateTime = DateTime.MinValue;
                if (lastUsed.TryGetValue(hash, out dateTime))
                {
                    lastUsed.TryUpdate(hash, DateTime.Now, dateTime);
                }
            }
            else
            {
                conn = new RserveConnection(node.rserveParameter);
                Thread.Sleep(500);
                rserveConns.TryAdd(hash, conn);
                lastUsed.TryAdd(hash, DateTime.Now);
            }

            return(conn);
        }
예제 #2
0
        private void HandleError(Exception ex, RserveConnection rserveConn)
        {
            String msg;

            try
            {
                msg = rserveConn.Connection.Eval("geterrmessage()").AsString;
                if (String.IsNullOrWhiteSpace(msg))
                {
                    msg = ex.Message;
                }

                logger.Warn("Rserve error: {0}", msg);
            }
            catch
            {
                logger.Warn("Rserve error: {0}", ex.Message);
                throw new RpcException(new Status(StatusCode.Unavailable, $"Rserve error: {ex.Message}"));
            }

            // Try to get the stack trace
            // It's possible that geterrmessage() succeeds and traceback() fails.
            try
            {
                var tracebacks = rserveConn.Connection.Eval("traceback()").AsStrings;
                var traceback  = String.Join("\r\n", tracebacks);
                logger.Warn("Rserve Traceback: {0}", traceback);
            }
            catch
            {
                // Error msg already logged
            }
            throw new RpcException(new Status(StatusCode.InvalidArgument, $"Rserve error: {msg}"));
        }
예제 #3
0
        private void HandleZeroRowsFromRserve(RserveConnection rserveConn)
        {
            String msg = $"No data returned from R script execution. Possible error in script: ";

            try
            {
                String errMsg = rserveConn.Connection.Eval("geterrmessage()").AsString;

                if (!String.IsNullOrWhiteSpace(errMsg))
                {
                    msg = msg + errMsg;
                }

                logger.Warn("{0}", msg);
            }
            catch
            {
                throw new RpcException(new Status(StatusCode.Unknown, $"{msg}"));
            }

            // Try to get the stack trace
            // It's possible that geterrmessage() succeeds and traceback() fails.
            try
            {
                var tracebacks = rserveConn.Connection.Eval("traceback()").AsStrings;
                var traceback  = String.Join("\r\n", tracebacks);
                logger.Warn("Rserve Traceback when no data returned from R script execution: {0}", traceback);
            }
            catch
            {
                // Error msg already logged
            }
            throw new RpcException(new Status(StatusCode.InvalidArgument, $"{msg}"));
        }
예제 #4
0
        public RServeEvaluator(RserveParameter para)
        {
            connPool   = new RserveConnectionPool();
            rservePara = para;
            RserveConnection rserveConnInitial = connPool.GetConnection(rservePara);

            logger.Trace($"Rserve connection initiated: {rserveConnInitial!=null}");
        }
예제 #5
0
        public RServeEvaluator(RserveParameter para, bool enableScript, string functionDefinitionsFile)
        {
            allowScript = enableScript;
            if (!String.IsNullOrEmpty(functionDefinitionsFile))
            {
                definedFunctions = new DefinedFunctions(functionDefinitionsFile);
            }
            CreateCapabilities();
            connPool   = new RserveConnectionPool();
            rservePara = para;

            RserveConnection rserveConnInitial = connPool.GetConnection(rservePara);

            logger.Trace($"Rserve connection initiated: {rserveConnInitial != null}");
        }
예제 #6
0
        public RserveConnection GetConnection(RserveParameter rserveParams)
        {
            var hash = rserveParams.GetHashCode().ToString();
            RserveConnection conn = null;

            if (rserveConns.ContainsKey(hash))
            {
                rserveConns.TryGetValue(hash, out conn);
                var dateTime = DateTime.MinValue;
                if (lastUsed.TryGetValue(hash, out dateTime))
                {
                    lastUsed.TryUpdate(hash, DateTime.Now, dateTime);
                }
            }
            else
            {
                conn = new RserveConnection(rserveParams);
                Thread.Sleep(500);
                rserveConns.TryAdd(hash, conn);
                lastUsed.TryAdd(hash, DateTime.Now);
            }

            return(conn);
        }
예제 #7
0
        async Task <Sexp> EvaluateScriptInRserve(SexpList inputDataFrame, int reqHash, string rScript, RserveConnection rserveConn)
        {
            await semaphoreRserve.WaitAsync();

            try
            {
                if (inputDataFrame != null && inputDataFrame.Count > 0)
                {
                    rserveConn.Connection["q"] = inputDataFrame;
                }
                logger.Debug($"Evaluating R script, hashid ({reqHash}): {rScript}");

                var res = rserveConn.Connection.Eval(rScript);
                logger.Info($"Rserve result: {res.Count} rows, hashid ({reqHash})");
                if (res.Count == 0)
                {
                    HandleZeroRowsFromRserve(rserveConn);
                }

                return(res);
            }
            catch (Exception e)
            {
                HandleError(e, rserveConn);
                return(null);
            }
            finally
            {
                semaphoreRserve.Release();
            }
        }
예제 #8
0
        async Task <Sexp> EvaluateScriptInRserve(SexpList inputDataFrame, int reqHash, string rScript, RserveConnection rserveConn)
        {
            var stopwatch = new Stopwatch();

            stopwatch.Start();
            await rserveConn.semaphoreRserve.WaitAsync();

            stopwatch.Stop();
            logger.Trace($"Wait For Connection Took {stopwatch.ElapsedMilliseconds} ms, hashid ({reqHash})");
            try
            {
                if (inputDataFrame != null && inputDataFrame.Count > 0)
                {
                    rserveConn.Connection["q"] = inputDataFrame;
                }
                logger.Debug($"Evaluating R script, hashid ({reqHash}): {rScript}");

                var res = rserveConn.Connection.Eval(rScript);
                logger.Info($"Rserve result: {res.Count} rows, hashid ({reqHash})");
                if (res.Count == 0)
                {
                    HandleZeroRowsFromRserve(rserveConn);
                }

                return(res);
            }
            catch (Exception e)
            {
                HandleError(e, rserveConn);
                return(null);
            }
            finally
            {
                rserveConn.semaphoreRserve.Release();
            }
        }
예제 #9
0
        private async Task GenerateResult(Sexp RResult, IServerStreamWriter <global::Qlik.Sse.BundledRows> responseStream, RserveConnection rserveConn)
        {
            if (RResult is SexpArrayBool || RResult is SexpArrayDouble || RResult is SexpArrayInt)
            {
                var bundledRows = new BundledRows();
                var numerics    = RResult.AsDoubles;
                if (numerics.Length == 0)
                {
                    HandleZeroRowsFromRserve(rserveConn);
                }

                for (int i = 0; i < numerics.Length; i++)
                {
                    var row = new Row();
                    row.Duals.Add(new Dual()
                    {
                        NumData = numerics[i]
                    });
                    bundledRows.Rows.Add(row);
                    if ((i % 2000) == 0)
                    {
                        // Send a bundle
                        await responseStream.WriteAsync(bundledRows);

                        bundledRows = new BundledRows();
                    }
                }

                if (bundledRows.Rows.Count() > 0)
                {
                    // Send last bundle
                    await responseStream.WriteAsync(bundledRows);
                }

                if (logger.IsTraceEnabled)
                {
                    var logNumerics = String.Join(", ", numerics);
                    logger.Trace("Numeric result column data: {0}", logNumerics);
                }
            }
            else if (RResult is SexpArrayString)
            {
                var bundledRows = new BundledRows();
                var strings     = RResult.AsStrings;
                if (strings.Length == 0)
                {
                    HandleZeroRowsFromRserve(rserveConn);
                }

                for (int i = 0; i < strings.Length; i++)
                {
                    var row = new Row();
                    row.Duals.Add(new Dual()
                    {
                        StrData = strings[i] ?? ""
                    });
                    bundledRows.Rows.Add(row);
                    if ((i % 2000) == 0)
                    {
                        // Send a bundle
                        await responseStream.WriteAsync(bundledRows);

                        bundledRows = new BundledRows();
                    }
                }

                if (bundledRows.Rows.Count() > 0)
                {
                    // Send last bundle
                    await responseStream.WriteAsync(bundledRows);
                }

                if (logger.IsTraceEnabled)
                {
                    var logStrings = String.Join(", ", strings);
                    logger.Trace("String result column data: {0}", logStrings);
                }
            }
            else
            {
                throw new NotImplementedException();
            }
        }
예제 #10
0
        async Task AddInputData(Parameter[] Parameters, IAsyncStreamReader <global::Qlik.Sse.BundledRows> requestStream, RserveConnection rserveConn)
        {
            var Params = GetParams(Parameters);

            await ConvertToColumnar(Params, requestStream);

            var data = new List <KeyValuePair <string, object> >();

            for (int i = 0; i < Params.Length; i++)
            {
                var s = GenerateData(Params[i]);
                data.Add(new KeyValuePair <string, object>(Parameters[i].Name, s));
            }
            rserveConn.Connection["q"] = Sexp.MakeDataFrame(data);
        }