use of org.json_voltpatches.JSONObject in project voltdb by VoltDB.
the class SnapshotDaemon method initiateSnapshotSave.
private void initiateSnapshotSave(final long handle, final Object[] params, boolean blocking) {
boolean success = true;
VoltTable checkResult = SnapshotUtil.constructNodeResultsTable();
final String jsString = String.class.cast(params[0]);
if (m_lastInitiationTs != null) {
final long elapsedMs = System.currentTimeMillis() - m_lastInitiationTs.getFirst();
// Blocking snapshot may take a long time to finish, don't time it out if it's blocking
if (!m_lastInitiationTs.getSecond() && elapsedMs > INITIATION_RESPONSE_TIMEOUT_MS) {
SNAP_LOG.warn(String.format("A snapshot was initiated %d minutes ago and hasn't received a response yet.", TimeUnit.MILLISECONDS.toMinutes(elapsedMs)));
m_lastInitiationTs = null;
} else {
checkResult.addRow(CoreUtils.getHostIdFromHSId(m_mb.getHSId()), CoreUtils.getHostnameOrAddress(), null, "FAILURE", "SNAPSHOT IN PROGRESS");
success = false;
}
}
if (success) {
try {
final JSONObject jsObj = new JSONObject(jsString);
boolean initiateSnapshot;
// Do scan work on all known live hosts
VoltMessage msg = new SnapshotCheckRequestMessage(jsString);
SnapshotPathType pathType = SnapshotPathType.valueOf(jsObj.getString(SnapshotUtil.JSON_PATH_TYPE));
Set<Integer> liveHosts = VoltDB.instance().getHostMessenger().getLiveHostIds();
for (int hostId : liveHosts) {
m_mb.send(CoreUtils.getHSIdFromHostAndSite(hostId, HostMessenger.SNAPSHOT_IO_AGENT_ID), msg);
}
// Wait for responses from all hosts for a certain amount of time
Map<Integer, VoltTable> responses = Maps.newHashMap();
// 10s timeout
final long timeoutMs = 10 * 1000;
final long endTime = System.currentTimeMillis() + timeoutMs;
SnapshotCheckResponseMessage response;
while ((response = (SnapshotCheckResponseMessage) m_mb.recvBlocking(timeoutMs)) != null) {
final String nonce = jsObj.getString(SnapshotUtil.JSON_NONCE);
boolean nonceFound = false;
if (pathType == SnapshotPathType.SNAP_PATH) {
// If request was explicitely PATH check path too.
if (nonce.equals(response.getNonce()) && response.getPath().equals(jsObj.getString(SnapshotUtil.JSON_PATH))) {
nonceFound = true;
}
} else {
// If request is with type other than path just check type.
if (nonce.equals(response.getNonce()) && response.getSnapshotPathType() == pathType) {
nonceFound = true;
}
}
if (nonceFound) {
responses.put(CoreUtils.getHostIdFromHSId(response.m_sourceHSId), response.getResponse());
}
if (responses.size() == liveHosts.size() || System.currentTimeMillis() > endTime) {
break;
}
}
if (responses.size() != liveHosts.size()) {
checkResult.addRow(CoreUtils.getHostIdFromHSId(m_mb.getHSId()), CoreUtils.getHostnameOrAddress(), null, "FAILURE", "TIMED OUT CHECKING SNAPSHOT FEASIBILITY");
success = false;
}
if (success) {
// TRAIL [TruncSnap:12] all participating nodes have initiated successfully
// Call @SnapshotSave if check passed, return the failure otherwise
checkResult = VoltTableUtil.unionTables(responses.values());
initiateSnapshot = SnapshotUtil.didSnapshotRequestSucceed(new VoltTable[] { checkResult });
if (initiateSnapshot) {
m_lastInitiationTs = Pair.of(System.currentTimeMillis(), blocking);
m_initiator.initiateSnapshotDaemonWork("@SnapshotSave", handle, params);
} else {
success = false;
}
}
} catch (JSONException e) {
success = false;
checkResult.addRow(CoreUtils.getHostIdFromHSId(m_mb.getHSId()), CoreUtils.getHostnameOrAddress(), null, "FAILURE", "ERROR PARSING JSON");
SNAP_LOG.warn("Error parsing JSON string: " + jsString, e);
}
}
if (!success) {
final ClientResponseImpl failureResponse = new ClientResponseImpl(ClientResponseImpl.SUCCESS, new VoltTable[] { checkResult }, null);
failureResponse.setClientHandle(handle);
processClientResponse(Callables.returning(failureResponse));
}
}
use of org.json_voltpatches.JSONObject in project voltdb by VoltDB.
the class SnapshotCompletionMonitor method processSnapshotData.
private void processSnapshotData(byte[] data) throws Exception {
if (data == null) {
return;
}
JSONObject jsonObj = new JSONObject(new String(data, "UTF-8"));
long txnId = jsonObj.getLong("txnId");
int hostCount = jsonObj.getInt("hostCount");
String path = jsonObj.getString(SnapshotUtil.JSON_PATH);
SnapshotPathType stype = SnapshotPathType.valueOf(jsonObj.getString(SnapshotUtil.JSON_PATH_TYPE));
String nonce = jsonObj.getString(SnapshotUtil.JSON_NONCE);
boolean truncation = jsonObj.getBoolean("isTruncation");
boolean didSucceed = jsonObj.getBoolean("didSucceed");
// A truncation request ID is not always provided. It's used for
// snapshots triggered indirectly via ZooKeeper so that the
// triggerer can recognize the snapshot when it finishes.
String truncReqId = jsonObj.optString("truncReqId");
if (hostCount == 0) {
/*
* Convert the JSON object containing the export sequence numbers for each
* table and partition to a regular map
*/
Map<String, Map<Integer, Pair<Long, Long>>> exportSequenceNumbers = null;
final JSONObject exportSequenceJSON = jsonObj.getJSONObject("exportSequenceNumbers");
final ImmutableMap.Builder<String, Map<Integer, Pair<Long, Long>>> builder = ImmutableMap.builder();
@SuppressWarnings("unchecked") final Iterator<String> tableKeys = exportSequenceJSON.keys();
while (tableKeys.hasNext()) {
final String tableName = tableKeys.next();
final JSONObject tableSequenceNumbers = exportSequenceJSON.getJSONObject(tableName);
ImmutableMap.Builder<Integer, Pair<Long, Long>> tableBuilder = ImmutableMap.builder();
@SuppressWarnings("unchecked") final Iterator<String> partitionKeys = tableSequenceNumbers.keys();
while (partitionKeys.hasNext()) {
final String partitionString = partitionKeys.next();
final Integer partitionId = Integer.valueOf(partitionString);
JSONObject sequenceNumbers = tableSequenceNumbers.getJSONObject(partitionString);
final Long ackOffset = sequenceNumbers.getLong("ackOffset");
final Long sequenceNumber = sequenceNumbers.getLong("sequenceNumber");
tableBuilder.put(partitionId, Pair.of(ackOffset, sequenceNumber));
}
builder.put(tableName, tableBuilder.build());
}
exportSequenceNumbers = builder.build();
long clusterCreateTime = jsonObj.optLong("clusterCreateTime", -1);
Map<Integer, Long> drSequenceNumbers = new HashMap<>();
JSONObject drTupleStreamJSON = jsonObj.getJSONObject("drTupleStreamStateInfo");
Iterator<String> partitionKeys = drTupleStreamJSON.keys();
int drVersion = 0;
while (partitionKeys.hasNext()) {
String partitionIdString = partitionKeys.next();
JSONObject stateInfo = drTupleStreamJSON.getJSONObject(partitionIdString);
drVersion = (int) stateInfo.getLong("drVersion");
drSequenceNumbers.put(Integer.valueOf(partitionIdString), stateInfo.getLong("sequenceNumber"));
}
Map<Integer, Long> partitionTxnIdsMap = ImmutableMap.of();
synchronized (m_snapshotTxnIdsToPartitionTxnIds) {
Map<Integer, Long> partitionTxnIdsList = m_snapshotTxnIdsToPartitionTxnIds.get(txnId);
if (partitionTxnIdsList != null) {
partitionTxnIdsMap = ImmutableMap.copyOf(partitionTxnIdsList);
}
}
/*
* Collect all the last seen ids from the remote data centers so they can
* be used by live rejoin to initialize a starting state for applying DR
* data
*/
Map<Integer, Map<Integer, Map<Integer, DRConsumerDrIdTracker>>> drMixedClusterSizeConsumerState = new HashMap<>();
JSONObject consumerPartitions = jsonObj.getJSONObject("drMixedClusterSizeConsumerState");
Iterator<String> cpKeys = consumerPartitions.keys();
while (cpKeys.hasNext()) {
final String consumerPartitionIdStr = cpKeys.next();
final Integer consumerPartitionId = Integer.valueOf(consumerPartitionIdStr);
JSONObject siteInfo = consumerPartitions.getJSONObject(consumerPartitionIdStr);
drMixedClusterSizeConsumerState.put(consumerPartitionId, ExtensibleSnapshotDigestData.buildConsumerSiteDrIdTrackersFromJSON(siteInfo));
}
Iterator<SnapshotCompletionInterest> iter = m_interests.iterator();
while (iter.hasNext()) {
SnapshotCompletionInterest interest = iter.next();
try {
interest.snapshotCompleted(new SnapshotCompletionEvent(path, stype, nonce, txnId, partitionTxnIdsMap, truncation, didSucceed, truncReqId, exportSequenceNumbers, Collections.unmodifiableMap(drSequenceNumbers), Collections.unmodifiableMap(drMixedClusterSizeConsumerState), drVersion, clusterCreateTime));
} catch (Exception e) {
SNAP_LOG.warn("Exception while executing snapshot completion interest", e);
}
}
}
}
use of org.json_voltpatches.JSONObject in project voltdb by VoltDB.
the class RestoreAgent method fetchSnapshotTxnId.
/**
* Get the txnId of the snapshot the cluster is restoring from from ZK.
* NOTE that the barrier for this is now completely contained
* in run() in the restorePlanner thread; nobody gets out of there until
* someone wins the leader election and successfully writes the VoltZK.restore_snapshot_id
* node, so we just need to read it here.
*/
private void fetchSnapshotTxnId() {
try {
byte[] data = m_zk.getData(VoltZK.restore_snapshot_id, false, null);
String jsonData = new String(data, Constants.UTF8ENCODING);
if (!jsonData.equals("{}")) {
m_hasRestored = true;
JSONObject jo = new JSONObject(jsonData);
SnapshotInfo info = new SnapshotInfo(jo);
m_replayAgent.setSnapshotTxnId(info);
} else {
m_hasRestored = false;
m_replayAgent.setSnapshotTxnId(null);
}
} catch (KeeperException e2) {
VoltDB.crashGlobalVoltDB(e2.getMessage(), false, e2);
} catch (InterruptedException e2) {
} catch (JSONException je) {
VoltDB.crashLocalVoltDB(je.getMessage(), true, je);
}
}
use of org.json_voltpatches.JSONObject in project voltdb by VoltDB.
the class SnapshotDaemon method createRequestNode.
/**
* Try to create the ZK node to request the snapshot.
*
* @param snapInfo SnapshotInitiationInfo object with the requested snapshot initiation settings
* @return The request ID if succeeded, otherwise null.
*/
private String createRequestNode(SnapshotInitiationInfo snapInfo) {
String requestId = null;
try {
requestId = java.util.UUID.randomUUID().toString();
if (!snapInfo.isTruncationRequest()) {
final JSONObject jsObj = snapInfo.getJSONObjectForZK();
jsObj.put("requestId", requestId);
String zkString = jsObj.toString(4);
byte[] zkBytes = zkString.getBytes("UTF-8");
m_zk.create(VoltZK.user_snapshot_request, zkBytes, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
} else {
m_zk.create(VoltZK.request_truncation_snapshot_node, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
}
} catch (KeeperException.NodeExistsException e) {
return null;
} catch (Exception e) {
VoltDB.crashLocalVoltDB("Exception while attempting to create user snapshot request in ZK", true, e);
}
return requestId;
}
use of org.json_voltpatches.JSONObject in project voltdb by VoltDB.
the class SnapshotScanAgent method parseParams.
// Parse the provided parameter set object and fill in subselector and interval into
// the provided JSONObject. If there's an error, return that in the String, otherwise
// return null. Yes, ugly. Bang it out, then refactor later.
private String parseParams(ParameterSet params, JSONObject obj) throws Exception {
String path = null;
if (params.toArray().length != 1) {
return "Incorrect number of arguments to @SnapshotScan (expects 1, received " + params.toArray().length + ")";
}
Object first = params.toArray()[0];
if (!(first instanceof String)) {
return "First argument to @SnapshotScan must be a valid STRING path, instead was " + first;
}
path = (String) first;
if (path == null || path == "") {
return "Provided path was null or the empty string";
}
// Dupe SNAPSHOTSCAN as the subselector in case we consolidate later
obj.put("subselector", "SNAPSHOTSCAN");
obj.put("interval", false);
obj.put("path", path);
return null;
}
Aggregations