/*
* Copyright 2015-present Facebook, 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.facebook.buck.artifact_cache;
import com.facebook.buck.event.AbstractBuckEvent;
import com.facebook.buck.event.EventKey;
import com.facebook.buck.event.LeafEvent;
import com.facebook.buck.rules.RuleKey;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.util.Optional;
public abstract class ArtifactCacheEvent extends AbstractBuckEvent implements LeafEvent {
private static final String TARGET_KEY = "TARGET";
public enum Operation {
FETCH,
STORE,
}
public enum InvocationType {
SYNCHRONOUS,
ASYNCHRONOUS,
}
public enum CacheMode {
dir,
http
}
@JsonIgnore private final CacheMode cacheMode;
@JsonProperty("operation")
private final Operation operation;
@JsonIgnore private final ArtifactCacheEvent.InvocationType invocationType;
@JsonIgnore private final Optional<String> target;
@JsonIgnore private final ImmutableSet<RuleKey> ruleKeys;
protected ArtifactCacheEvent(
EventKey eventKey,
CacheMode cacheMode,
Operation operation,
Optional<String> target,
ImmutableSet<RuleKey> ruleKeys,
ArtifactCacheEvent.InvocationType invocationType) {
super(eventKey);
this.cacheMode = cacheMode;
this.operation = operation;
this.target = target;
this.ruleKeys = ruleKeys;
this.invocationType = invocationType;
}
@Override
protected String getValueString() {
return getEventName() + getEventKey().toString();
}
@Override
public String getCategory() {
return cacheMode.toString().toLowerCase() + "_artifact_" + operation.toString().toLowerCase();
}
public Operation getOperation() {
return operation;
}
public ImmutableSet<RuleKey> getRuleKeys() {
return ruleKeys;
}
public Optional<String> getTarget() {
return target;
}
public ArtifactCacheEvent.InvocationType getInvocationType() {
return invocationType;
}
@Override
public abstract String getEventName();
public static final Optional<String> getTarget(final ImmutableMap<String, String> metadata) {
return metadata.containsKey(TARGET_KEY)
? Optional.of(metadata.get(TARGET_KEY))
: Optional.empty();
}
public abstract static class Started extends ArtifactCacheEvent {
protected Started(
EventKey eventKey,
CacheMode cacheMode,
Operation operation,
Optional<String> target,
ImmutableSet<RuleKey> ruleKeys,
ArtifactCacheEvent.InvocationType invocationType) {
super(eventKey, cacheMode, operation, target, ruleKeys, invocationType);
}
}
public abstract static class Finished extends ArtifactCacheEvent {
/** Not present iff {@link #getOperation()} is not {@link Operation#FETCH}. */
private final Optional<CacheResult> cacheResult;
protected Finished(
EventKey eventKey,
CacheMode cacheMode,
Operation operation,
Optional<String> target,
ImmutableSet<RuleKey> ruleKeys,
ArtifactCacheEvent.InvocationType invocationType,
Optional<CacheResult> cacheResult) {
super(eventKey, cacheMode, operation, target, ruleKeys, invocationType);
Preconditions.checkArgument(
(!operation.equals(Operation.FETCH) || cacheResult.isPresent()),
"For FETCH operations, cacheResult must be non-null. "
+ "For non-FETCH operations, cacheResult must be null.");
this.cacheResult = cacheResult;
}
public Optional<CacheResult> getCacheResult() {
return cacheResult;
}
public boolean isSuccess() {
return !cacheResult.isPresent() || cacheResult.get().getType().isSuccess();
}
@Override
public boolean equals(Object o) {
if (!super.equals(o)) {
return false;
}
// Because super.equals compares the EventKey, getting here means that we've somehow managed
// to create 2 Finished events for the same Started event.
throw new UnsupportedOperationException("Multiple conflicting Finished events detected.");
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), cacheResult);
}
}
}