Search in sources :

Example 1 with ProcedureRunner

use of org.voltdb.ProcedureRunner in project voltdb by VoltDB.

the class FragmentTask method processFragmentTask.

// Cut and pasted from ExecutionSite processFragmentTask(), then
// modifed to work in the new world
public FragmentResponseMessage processFragmentTask(SiteProcedureConnection siteConnection) {
    // Ensure default procs loaded here
    // Also used for LoadMultipartitionTable
    String procNameToLoad = m_fragmentMsg.getProcNameToLoad();
    if (procNameToLoad != null) {
        // this will ensure proc is loaded
        ProcedureRunner runner = siteConnection.getProcedureRunner(procNameToLoad);
        assert (runner != null);
    }
    // IZZY: actually need the "executor" HSId these days?
    final FragmentResponseMessage currentFragResponse = new FragmentResponseMessage(m_fragmentMsg, m_initiator.getHSId());
    currentFragResponse.setStatus(FragmentResponseMessage.SUCCESS, null);
    if (m_inputDeps != null) {
        siteConnection.stashWorkUnitDependencies(m_inputDeps);
    }
    if (m_fragmentMsg.isEmptyForRestart()) {
        int outputDepId = m_fragmentMsg.getOutputDepId(0);
        currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(outputDepId, m_rawDummyResponse, 0, m_rawDummyResponse.length));
        return currentFragResponse;
    }
    ProcedureRunner currRunner = siteConnection.getProcedureRunner(m_fragmentMsg.getProcedureName());
    long[] executionTimes = null;
    int succeededFragmentsCount = 0;
    if (currRunner != null) {
        currRunner.getExecutionEngine().setPerFragmentTimingEnabled(m_fragmentMsg.isPerFragmentStatsRecording());
        if (m_fragmentMsg.isPerFragmentStatsRecording()) {
            // At this point, we will execute the fragments one by one.
            executionTimes = new long[1];
        }
    }
    for (int frag = 0; frag < m_fragmentMsg.getFragmentCount(); frag++) {
        byte[] planHash = m_fragmentMsg.getPlanHash(frag);
        final int outputDepId = m_fragmentMsg.getOutputDepId(frag);
        ParameterSet params = m_fragmentMsg.getParameterSetForFragment(frag);
        final int inputDepId = m_fragmentMsg.getOnlyInputDepId(frag);
        long fragmentId = 0;
        byte[] fragmentPlan = null;
        /*
             * Currently the error path when executing plan fragments
             * does not adequately distinguish between fatal errors and
             * abort type errors that should result in a roll back.
             * Assume that it is ninja: succeeds or doesn't return.
             * No roll back support.
             *
             * AW in 2012, the preceding comment might be wrong,
             * I am pretty sure what we don't support is partial rollback.
             * The entire procedure will roll back successfully on failure
             */
        VoltTable dependency = null;
        try {
            FastDeserializer fragResult;
            fragmentPlan = m_fragmentMsg.getFragmentPlan(frag);
            String stmtText = null;
            // if custom fragment, load the plan and get local fragment id
            if (fragmentPlan != null) {
                // statement text for unplanned fragments are pulled from the message,
                // to ensure that we get the correct constants from the most recent
                // invocation.
                stmtText = m_fragmentMsg.getStmtText(frag);
                fragmentId = ActivePlanRepository.loadOrAddRefPlanFragment(planHash, fragmentPlan, null);
            } else // otherwise ask the plan source for a local fragment id
            {
                fragmentId = ActivePlanRepository.getFragmentIdForPlanHash(planHash);
                stmtText = ActivePlanRepository.getStmtTextForPlanHash(planHash);
            }
            // set up the batch context for the fragment set
            siteConnection.setBatch(m_fragmentMsg.getCurrentBatchIndex());
            fragResult = siteConnection.executePlanFragments(1, new long[] { fragmentId }, new long[] { inputDepId }, new ParameterSet[] { params }, null, // for long-running queries
            stmtText == null ? null : new String[] { stmtText }, // FragmentTasks don't generate statement hashes,
            new boolean[] { false }, null, m_txnState.txnId, m_txnState.m_spHandle, m_txnState.uniqueId, m_txnState.isReadOnly(), VoltTrace.log(VoltTrace.Category.EE) != null);
            // get a copy of the result buffers from the cache buffer so we can post the
            // fragment response to the network
            final int tableSize;
            final byte[] fullBacking;
            try {
                // read the complete size of the buffer used
                fragResult.readInt();
                // read number of dependencies (1)
                fragResult.readInt();
                // read the dependencyId() -1;
                fragResult.readInt();
                tableSize = fragResult.readInt();
                fullBacking = new byte[tableSize];
                // get a copy of the buffer
                fragResult.readFully(fullBacking);
            } catch (final IOException ex) {
                LOG.error("Failed to deserialze result table" + ex);
                throw new EEException(ExecutionEngine.ERRORCODE_WRONG_SERIALIZED_BYTES);
            }
            if (hostLog.isTraceEnabled()) {
                hostLog.l7dlog(Level.TRACE, LogKeys.org_voltdb_ExecutionSite_SendingDependency.name(), new Object[] { outputDepId }, null);
            }
            currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(outputDepId, fullBacking, 0, tableSize));
        } catch (final EEException e) {
            hostLog.l7dlog(Level.TRACE, LogKeys.host_ExecutionSite_ExceptionExecutingPF.name(), new Object[] { Encoder.hexEncode(planHash) }, e);
            currentFragResponse.setStatus(FragmentResponseMessage.UNEXPECTED_ERROR, e);
            if (currentFragResponse.getTableCount() == 0) {
                // Make sure the response has at least 1 result with a valid DependencyId
                currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(outputDepId, m_rawDummyResult, 0, m_rawDummyResult.length));
            }
            break;
        } catch (final SQLException e) {
            hostLog.l7dlog(Level.TRACE, LogKeys.host_ExecutionSite_ExceptionExecutingPF.name(), new Object[] { Encoder.hexEncode(planHash) }, e);
            currentFragResponse.setStatus(FragmentResponseMessage.UNEXPECTED_ERROR, e);
            if (currentFragResponse.getTableCount() == 0) {
                // Make sure the response has at least 1 result with a valid DependencyId
                currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(outputDepId, m_rawDummyResult, 0, m_rawDummyResult.length));
            }
            break;
        } catch (final InterruptException e) {
            hostLog.l7dlog(Level.TRACE, LogKeys.host_ExecutionSite_ExceptionExecutingPF.name(), new Object[] { Encoder.hexEncode(planHash) }, e);
            currentFragResponse.setStatus(FragmentResponseMessage.UNEXPECTED_ERROR, e);
            if (currentFragResponse.getTableCount() == 0) {
                // Make sure the response has at least 1 result with a valid DependencyId
                currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(outputDepId, m_rawDummyResult, 0, m_rawDummyResult.length));
            }
            break;
        } finally {
            // ensure adhoc plans are unloaded
            if (fragmentPlan != null) {
                ActivePlanRepository.decrefPlanFragmentById(fragmentId);
            }
            // The single-partition stored procedure handler is in the ProcedureRunner.
            if (currRunner != null) {
                succeededFragmentsCount = currRunner.getExecutionEngine().extractPerFragmentStats(1, executionTimes);
                long stmtDuration = 0;
                int stmtResultSize = 0;
                int stmtParameterSetSize = 0;
                if (m_fragmentMsg.isPerFragmentStatsRecording()) {
                    stmtDuration = executionTimes == null ? 0 : executionTimes[0];
                    stmtResultSize = dependency == null ? 0 : dependency.getSerializedSize();
                    stmtParameterSetSize = params == null ? 0 : params.getSerializedSize();
                }
                currRunner.getStatsCollector().endFragment(m_fragmentMsg.getStmtName(frag), m_fragmentMsg.isCoordinatorTask(), succeededFragmentsCount == 0, m_fragmentMsg.isPerFragmentStatsRecording(), stmtDuration, stmtResultSize, stmtParameterSetSize);
            }
        }
    }
    return currentFragResponse;
}
Also used : ParameterSet(org.voltdb.ParameterSet) FastDeserializer(org.voltdb.messaging.FastDeserializer) SQLException(org.voltdb.exceptions.SQLException) InterruptException(org.voltdb.exceptions.InterruptException) IOException(java.io.IOException) VoltTable(org.voltdb.VoltTable) ProcedureRunner(org.voltdb.ProcedureRunner) FragmentResponseMessage(org.voltdb.messaging.FragmentResponseMessage) EEException(org.voltdb.exceptions.EEException) DependencyPair(org.voltdb.DependencyPair)

Example 2 with ProcedureRunner

use of org.voltdb.ProcedureRunner in project voltdb by VoltDB.

the class ProcedureTask method processInitiateTask.

/** Mostly copy-paste of old ExecutionSite.processInitiateTask() */
protected InitiateResponseMessage processInitiateTask(Iv2InitiateTaskMessage task, SiteProcedureConnection siteConnection) {
    final InitiateResponseMessage response = new InitiateResponseMessage(task);
    try {
        Object[] callerParams = null;
        /*
             * Parameters are lazily deserialized. We may not find out until now
             * that the parameter set is corrupt
             */
        try {
            callerParams = task.getParameters();
        } catch (RuntimeException e) {
            Writer result = new StringWriter();
            PrintWriter pw = new PrintWriter(result);
            e.printStackTrace(pw);
            response.setResults(new ClientResponseImpl(ClientResponse.GRACEFUL_FAILURE, new VoltTable[] {}, "Exception while deserializing procedure params, procedure=" + m_procName + "\n" + result.toString()));
        }
        if (callerParams == null) {
            return response;
        }
        ClientResponseImpl cr = null;
        ProcedureRunner runner = siteConnection.getProcedureRunner(m_procName);
        if (runner == null) {
            String error = "Procedure " + m_procName + " is not present in the catalog. " + "This can happen if a catalog update removing the procedure occurred " + "after the procedure was submitted " + "but before the procedure was executed.";
            RateLimitedLogger.tryLogForMessage(System.currentTimeMillis(), 60, TimeUnit.SECONDS, hostLog, Level.WARN, error + " %s", "This log message is rate limited to once every 60 seconds.");
            response.setResults(new ClientResponseImpl(ClientResponse.UNEXPECTED_FAILURE, new VoltTable[] {}, error));
            return response;
        }
        // Check partitioning of single-partition and n-partition transactions.
        if (runner.checkPartition(m_txnState, siteConnection.getCurrentHashinator())) {
            runner.setupTransaction(m_txnState);
            // execute the procedure
            cr = runner.call(callerParams);
            // pass in the first value in the hashes array if it's not null
            Integer hash = null;
            int[] hashes = cr.getHashes();
            if (hashes != null && hashes.length > 0) {
                hash = hashes[0];
            }
            m_txnState.setHash(hash);
            //Don't pay the cost of returning the result tables for a replicated write
            //With reads don't apply the optimization just in case
            //                    if (!task.shouldReturnResultTables() && !task.isReadOnly()) {
            //                        cr.dropResultTable();
            //                    }
            response.setResults(cr);
            //  have the real results
            if ((!task.isReadOnly()) && task.isSinglePartition()) {
                m_txnState.storeResults(cr);
            }
        } else {
            // mis-partitioned invocation, reject it and let the ClientInterface restart it
            response.setMispartitioned(true, task.getStoredProcedureInvocation(), TheHashinator.getCurrentVersionedConfig());
        }
    } catch (final ExpectedProcedureException e) {
        execLog.l7dlog(Level.TRACE, LogKeys.org_voltdb_ExecutionSite_ExpectedProcedureException.name(), e);
        response.setResults(new ClientResponseImpl(ClientResponse.GRACEFUL_FAILURE, new VoltTable[] {}, e.toString()));
    } catch (final Exception e) {
        // Should not be able to reach here. VoltProcedure.call caught all invocation target exceptions
        // and converted them to error responses. Java errors are re-thrown, and not caught by this
        // exception clause. A truly unexpected exception reached this point. Crash. It's a defect.
        hostLog.l7dlog(Level.ERROR, LogKeys.host_ExecutionSite_UnexpectedProcedureException.name(), e);
        VoltDB.crashLocalVoltDB(e.getMessage(), true, e);
    }
    return response;
}
Also used : InitiateResponseMessage(org.voltdb.messaging.InitiateResponseMessage) VoltTable(org.voltdb.VoltTable) ExpectedProcedureException(org.voltdb.ExpectedProcedureException) StringWriter(java.io.StringWriter) ProcedureRunner(org.voltdb.ProcedureRunner) ExpectedProcedureException(org.voltdb.ExpectedProcedureException) ClientResponseImpl(org.voltdb.ClientResponseImpl) PrintWriter(java.io.PrintWriter) StringWriter(java.io.StringWriter) Writer(java.io.Writer) PrintWriter(java.io.PrintWriter)

Aggregations

ProcedureRunner (org.voltdb.ProcedureRunner)2 VoltTable (org.voltdb.VoltTable)2 IOException (java.io.IOException)1 PrintWriter (java.io.PrintWriter)1 StringWriter (java.io.StringWriter)1 Writer (java.io.Writer)1 ClientResponseImpl (org.voltdb.ClientResponseImpl)1 DependencyPair (org.voltdb.DependencyPair)1 ExpectedProcedureException (org.voltdb.ExpectedProcedureException)1 ParameterSet (org.voltdb.ParameterSet)1 EEException (org.voltdb.exceptions.EEException)1 InterruptException (org.voltdb.exceptions.InterruptException)1 SQLException (org.voltdb.exceptions.SQLException)1 FastDeserializer (org.voltdb.messaging.FastDeserializer)1 FragmentResponseMessage (org.voltdb.messaging.FragmentResponseMessage)1 InitiateResponseMessage (org.voltdb.messaging.InitiateResponseMessage)1