blob: f824cbda67277ec4808e2c0fbe11b865e3ade44a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
#include "EntryExpiryTask.hpp"
#include "CacheImpl.hpp"
#include "RegionInternal.hpp"
#include "Utils.hpp"
namespace apache {
namespace geode {
namespace client {
EntryExpiryTask::EntryExpiryTask(ExpiryTaskManager& manager,
std::shared_ptr<RegionInternal> region,
std::shared_ptr<MapEntryImpl> entry,
ExpirationAction action,
const duration_t& duration)
: ExpiryTask(manager),
duration_(duration),
action_(action),
entry_(entry),
region_(region) {}
EntryExpiryTask::time_point_t EntryExpiryTask::expire_at() const {
auto& properties = entry_->getExpProperties();
auto last_time = properties.last_accessed();
if (region_->getAttributes().getEntryTimeToLive() >
std::chrono::seconds::zero()) {
last_time = properties.last_modified();
}
return last_time + duration_;
}
bool EntryExpiryTask::on_expire() {
auto tp = expire_at();
if (tp > ExpiryTask::clock_t::now()) {
// Entry expiration needs to be re-scheduled as it was accessed/modified
// since the last time the expiration task was (re-)scheduled.
// This is the best approach, rather than re-scheduling the task each time
// the entry is accessed/modified, as access/modify is a more frequent
// event than expiration.
reset(tp);
return false;
}
// Pass a blank version tag.
std::shared_ptr<CacheableKey> key;
std::shared_ptr<VersionTag> versionTag;
entry_->getKeyI(key);
const auto& full_path = region_->getFullPath();
auto key_str = Utils::nullSafeToString(key);
switch (action_) {
case ExpirationAction::INVALIDATE: {
LOGDEBUG(
"EntryExpiryTask::DoTheExpirationAction INVALIDATE "
"for region " +
full_path + " entry with key " + key_str);
region_->invalidateNoThrow(key, nullptr, -1, CacheEventFlags::EXPIRATION,
versionTag);
break;
}
case ExpirationAction::LOCAL_INVALIDATE: {
LOGDEBUG(
"EntryExpiryTask::DoTheExpirationAction LOCAL_INVALIDATE "
"for region " +
full_path + " entry with key " + key_str);
region_->invalidateNoThrow(
key, nullptr, -1,
CacheEventFlags::EXPIRATION | CacheEventFlags::LOCAL, versionTag);
break;
}
case ExpirationAction::DESTROY: {
LOGDEBUG(
"EntryExpiryTask::DoTheExpirationAction DESTROY "
"for region " +
full_path + " entry with key " + key_str);
region_->destroyNoThrow(key, nullptr, -1, CacheEventFlags::EXPIRATION,
versionTag);
break;
}
case ExpirationAction::LOCAL_DESTROY: {
LOGDEBUG(
"EntryExpiryTask::DoTheExpirationAction LOCAL_DESTROY "
"for region " +
full_path + " entry with key " + key_str);
region_->destroyNoThrow(
key, nullptr, -1,
CacheEventFlags::EXPIRATION | CacheEventFlags::LOCAL, versionTag);
break;
}
case ExpirationAction::INVALID_ACTION: {
LOGERROR(
"Unknown expiration action "
"%d for region %s for key %s",
action_, full_path.c_str(), key_str.c_str());
break;
}
}
return true;
}
} // namespace client
} // namespace geode
} // namespace apache