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

com.couchbase.transactions.components.ATREntry Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2021 Couchbase, Inc.
 *
 * 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.
 */

package com.couchbase.transactions.components;

import com.couchbase.client.core.annotation.Stability;
import com.couchbase.client.core.msg.kv.DurabilityLevel;
import com.couchbase.transactions.forwards.ForwardCompatibility;
import com.couchbase.transactions.support.AttemptStates;

import java.time.Duration;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Stability.Internal
public class ATREntry {
    private final String atrBucket;
    private final String atrId;
    private final String attemptId;
    private final Optional transactionId;
    private final AttemptStates state;
    private final Optional timestampStartMsecs;
    private final Optional timestampCommitMsecs;
    private final Optional timestampCompleteMsecs;
    private final Optional timestampRollBackMsecs;
    private final Optional timestampRolledBackMsecs;
    private final Optional expiresAfterMsecs;
    private final long cas;
    private final Optional> insertedIds;
    private final Optional> replacedIds;
    private final Optional> removedIds;
    private final Optional forwardCompatibility;
    // Added in ExtStoreDurability
    private final Optional durabilityLevel;

    public ATREntry(String atrBucket,
                    String atrId,
                    String attemptId,
                    Optional transactionId,
                    AttemptStates state,
                    Optional timestampStartMsecs,
                    Optional timestampCommitMsecs,
                    Optional timestampCompleteMsecs,
                    Optional timestampRollBackMsecs,
                    Optional timestampRolledBackMsecs,
                    Optional expiresAfterMsecs,
                    // Optional.empty() indicates the fields were not present
                    Optional> insertedIds,
                    Optional> replacedIds,
                    Optional> removedIds,
                    long cas,
                    Optional forwardCompatibility,
                    Optional durabilityLevel
    ) {
        Objects.requireNonNull(atrBucket);
        Objects.requireNonNull(atrId);
        Objects.requireNonNull(attemptId);
        Objects.requireNonNull(state);
        Objects.requireNonNull(timestampStartMsecs);
        Objects.requireNonNull(timestampCommitMsecs);
        Objects.requireNonNull(timestampCompleteMsecs);
        Objects.requireNonNull(timestampRollBackMsecs);
        Objects.requireNonNull(timestampRolledBackMsecs);
        Objects.requireNonNull(insertedIds);
        Objects.requireNonNull(replacedIds);
        Objects.requireNonNull(removedIds);
        Objects.requireNonNull(expiresAfterMsecs);
        Objects.requireNonNull(forwardCompatibility);
        Objects.requireNonNull(durabilityLevel);

        this.atrId = atrId;
        this.atrBucket = atrBucket;
        this.attemptId = attemptId;
        this.transactionId = transactionId;
        this.state = state;
        this.timestampStartMsecs = timestampStartMsecs;
        this.timestampCommitMsecs = timestampCommitMsecs;
        this.timestampCompleteMsecs = timestampCompleteMsecs;
        this.timestampRollBackMsecs = timestampRollBackMsecs;
        this.timestampRolledBackMsecs = timestampRolledBackMsecs;
        this.expiresAfterMsecs = expiresAfterMsecs;
        this.cas = cas;
        this.insertedIds = insertedIds;
        this.replacedIds = replacedIds;
        this.removedIds = removedIds;
        this.forwardCompatibility = forwardCompatibility;
        this.durabilityLevel = durabilityLevel;
    }


    public boolean hasExpired() {
        return hasExpired(0);
    }

    public boolean hasExpired(long safetyMarginMillis) {
        long casInMsecs = cas / 1000000;

        if (!expiresAfterMsecs.isPresent()) {
            // Should always be set, protocol bug if not
            return false;
        }

        return hasExpired(casInMsecs,
                expiresAfterMsecs.get() + safetyMarginMillis);
    }

    public boolean hasExpired(long cas, long txnExpiresAfterMsecs) {
        if (timestampStartMsecs.isPresent()) {
            return (cas - timestampStartMsecs.get()) > txnExpiresAfterMsecs;
        } else {
            return false;
        }
    }

    public long ageMsecs() {
        return (cas / 1000000) - timestampStartMsecs().orElse(0l);
    }

    public String atrId() {
        return atrId;
    }

    public String attemptId() {
        return attemptId;
    }


    /**
     * This was added with {ExtTransactionId}
     */
    public Optional transactionId() {
        return transactionId;
    }

    public AttemptStates state() {
        return state;
    }

    public Optional timestampStartMsecs() {
        return timestampStartMsecs;
    }

    public Optional timestampCommitMsecs() {
        return timestampCommitMsecs;
    }

    public Optional timestampCompleteMsecs() {
        return timestampCompleteMsecs;
    }

    public Optional timestampRollBackMsecs() {
        return timestampRollBackMsecs;
    }

    public Optional timestampRolledBackMsecs() {
        return timestampRolledBackMsecs;
    }

    /**
     * Returns the CAS of the ATR documenting containing this entry
     */
    public long cas() {
        return cas;
    }

    public Optional> insertedIds() {
        return insertedIds;
    }

    public Optional> replacedIds() {
        return replacedIds;
    }

    public Optional> removedIds() {
        return removedIds;
    }

    public Optional expiresAfterMsecs() {
        return expiresAfterMsecs;
    }

    public Optional forwardCompatibility() {
        return forwardCompatibility;
    }

    public Optional durabilityLevel() {
        return durabilityLevel;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("ATREntry{");
        sb.append("atr=").append(atrBucket).append('/').append(atrId);
        sb.append(",attemptId=").append(attemptId);
        sb.append(",state=").append(state);
        sb.append(",expires=").append(expiresAfterMsecs).append("ms");
        sb.append(",[age=").append(ageMsecs()).append("ms");
        long casInMsecs = cas / 1000000;
        sb.append(",cas=").append(cas);
        sb.append("ns/");
        sb.append(casInMsecs);
        sb.append("ms],inserted=").append(insertedIds);
        sb.append(",replaced=").append(replacedIds);
        sb.append(",removed=").append(removedIds);
        sb.append(",start=").append(timestampStartMsecs).append("ms");
        sb.append(",fc=").append(forwardCompatibility.map(Object::toString).orElse("none"));
        sb.append(",dl=").append(durabilityLevel.map(Object::toString).orElse("n/a"));
        sb.append('}');
        return sb.toString();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy