/* This file is part of VoltDB. * Copyright (C) 2008-2017 VoltDB Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ package txnIdSelfCheck; import org.voltcore.logging.VoltLogger; import org.voltdb.client.Client; import org.voltdb.client.ClientResponse; import org.voltdb.client.NoConnectionsException; import org.voltdb.client.ProcCallException; import java.io.IOException; public enum TxnId2Utils {; static VoltLogger log = new VoltLogger("TxnId2Utils"); static ClientResponse doAdHoc(Client client, String query) throws ProcCallException { return doProcCall(client, "@AdHoc", query); } static boolean isConnectionTransactionOrCatalogIssue(String statusString) { return statusString.matches("(?s).*AdHoc transaction -?[0-9]+ wasn.t planned against the current catalog version.*") || statusString.matches(".*Connection to database host \\(.*\\) was lost before a response was received.*") || statusString.matches(".*Transaction dropped due to change in mastership. It is possible the transaction was committed.*") || statusString.matches("(?s).*Transaction being restarted due to fault recovery or shutdown.*") || statusString.matches("(?s).*Invalid catalog update. Catalog or deployment change was planned against one version of the cluster configuration but that version was no longer live.*") || statusString.matches("(?s).*Ad Hoc Planner task queue is full.*"); } static boolean isServerUnavailableIssue(String statusString) { return statusString.matches("(?s).*No response received in the allotted time.*") || statusString.matches(".*Server is currently unavailable; try again later.*") || statusString.matches(".*Server is paused.*") || statusString.matches("(?s).*Server is shutting down.*"); } static boolean isConnectionTransactionCatalogOrServerUnavailableIssue(String statusString) { return isConnectionTransactionOrCatalogIssue(statusString) || isServerUnavailableIssue(statusString); } static boolean isTransactionStateIndeterminate(ClientResponse cr) { String statusString = cr.getStatusString(); return (statusString.matches("(?s).*No response received in the allotted time.*") || statusString.matches(".*Connection to database host \\(.*\\) was lost before a response was received.*")); } static ClientResponse doProcCall(Client client, String proc, Object... parms) throws ProcCallException { return doProcCall(client, proc, false, parms); } static ClientResponse doProcCallOneShot(Client client, String proc, Object... parms) throws ProcCallException { return doProcCall(client, proc, true, parms); } static ClientResponse doProcCall(Client client, String proc, boolean oneshot, Object... parms) throws ProcCallException { Boolean sleep = false; Boolean noConnections = false; ClientResponse cr = null; while (true) { try { if (proc == "@AdHoc") cr = client.callProcedure("@AdHoc", (String) parms[0]); else cr = client.callProcedure(proc, parms); if (cr.getStatus() == ClientResponse.SUCCESS) { Benchmark.txnCount.incrementAndGet(); return cr; } else { log.debug(cr.getStatusString()); Benchmark.hardStop("unexpected response", cr); } } catch (NoConnectionsException e) { noConnections = true; } catch (IOException e) { Benchmark.hardStop(e); } catch (ProcCallException e) { cr = e.getClientResponse(); String ss = cr.getStatusString(); log.debug(ss); if (isConnectionTransactionOrCatalogIssue(ss) ) { /* continue */ } else if (isServerUnavailableIssue(ss)) { sleep = true; } else { throw e; } } if (oneshot) return cr; if (sleep | noConnections) { try { Thread.sleep(3000); } catch (Exception f) { } sleep = false; if (noConnections) while (client.getConnectedHostList().size() == 0); noConnections = false; } } } static long getRowCount(Client client, String tableName) throws NoConnectionsException, IOException, ProcCallException { ClientResponse cr = doAdHoc(client, "select count(*) from " + tableName + ";"); return cr.getResults()[0].asScalarLong(); } }