All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.nosqlbench.driver.mongodb.MongoAction Maven / Gradle / Ivy

package io.nosqlbench.driver.mongodb;

/*
 * Copyright (c) 2022 nosqlbench
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */


import com.codahale.metrics.Timer;
import io.nosqlbench.engine.api.activityapi.core.SyncAction;
import io.nosqlbench.engine.api.activityapi.planning.OpSequence;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bson.Document;
import org.bson.conversions.Bson;

import java.util.concurrent.TimeUnit;

public class MongoAction implements SyncAction {

    private final static Logger logger = LogManager.getLogger(MongoAction.class);

    private final MongoActivity activity;
    private final int slot;

    private OpSequence sequencer;

    public MongoAction(MongoActivity activity, int slot) {
        this.activity = activity;
        this.slot = slot;
    }

    @Override
    public void init() {
        this.sequencer = activity.getOpSequencer();
    }

    @Override
    public int runCycle(long cycle) {
        ReadyMongoStatement rms;
        Bson queryBson;
        try (Timer.Context bindTime = activity.bindTimer.time()) {
            rms = sequencer.apply(cycle);
            queryBson = rms.bind(cycle);

            // Maybe show the query in log/console - only for diagnostic use
            if (activity.isShowQuery()) {
                logger.info("Query(cycle={}):\n{}", cycle, queryBson);
            }
        }

        long nanoStartTime = System.nanoTime();
        for (int i = 1; i <= activity.getMaxTries(); i++) {
            activity.triesHisto.update(i);

            try (Timer.Context resultTime = activity.resultTimer.time()) {
                // assuming the commands are one of these in the doc:
                // https://docs.mongodb.com/manual/reference/command/nav-crud/
                Document resultDoc = activity.getDatabase().runCommand(queryBson, rms.getReadPreference());

                long resultNanos = System.nanoTime() - nanoStartTime;

                // TODO: perhaps collect the operationTime from the resultDoc if any
                // https://docs.mongodb.com/manual/reference/method/db.runCommand/#command-response
                int ok = Double.valueOf((double) resultDoc.getOrDefault("ok", 0.0d)).intValue();
                if (ok == 1) {
                    // success
                    activity.resultSuccessTimer.update(resultNanos, TimeUnit.NANOSECONDS);
                }
                activity.resultSetSizeHisto.update(resultDoc.getInteger("n", 0));

                return ok == 1 ? 0 : 1;
            } catch (Exception e) {
                logger.error("Failed to runCommand {} on cycle {}, tries {}", queryBson, cycle, i, e);
            }
        }

        throw new RuntimeException(String.format("Exhausted max tries (%s) on cycle %s",
            activity.getMaxTries(), cycle));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy