[core] move from microsecond precision timestamp to integer second precision
This commit is contained in:
@@ -70,7 +70,7 @@ int main(int argc, char *argv[]) {
|
||||
: region(region_),
|
||||
fileSource(fileSource_),
|
||||
loop(loop_),
|
||||
start(SystemClock::now()) {
|
||||
start(util::now()) {
|
||||
}
|
||||
|
||||
void statusChanged(OfflineRegionStatus status) override {
|
||||
@@ -82,7 +82,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
std::string bytesPerSecond = "-";
|
||||
|
||||
auto elapsedSeconds = (SystemClock::now() - start) / 1s;
|
||||
auto elapsedSeconds = (util::now() - start) / 1s;
|
||||
if (elapsedSeconds != 0) {
|
||||
bytesPerSecond = util::toString(status.completedResourceSize / elapsedSeconds);
|
||||
}
|
||||
@@ -111,7 +111,7 @@ int main(int argc, char *argv[]) {
|
||||
OfflineRegion& region;
|
||||
DefaultFileSource& fileSource;
|
||||
util::RunLoop& loop;
|
||||
SystemTimePoint start;
|
||||
Timestamp start;
|
||||
};
|
||||
|
||||
static auto stop = [&] {
|
||||
|
||||
@@ -29,8 +29,14 @@ public:
|
||||
int8_t z;
|
||||
};
|
||||
|
||||
Resource(Kind kind_, const std::string& url_, optional<TileData> tileData_ = {})
|
||||
enum Necessity : bool {
|
||||
Optional = false,
|
||||
Required = true,
|
||||
};
|
||||
|
||||
Resource(Kind kind_, const std::string& url_, optional<TileData> tileData_ = {}, Necessity necessity_ = Required)
|
||||
: kind(kind_),
|
||||
necessity(necessity_),
|
||||
url(url_),
|
||||
tileData(std::move(tileData_)) {
|
||||
}
|
||||
@@ -41,7 +47,8 @@ public:
|
||||
float pixelRatio,
|
||||
int32_t x,
|
||||
int32_t y,
|
||||
int8_t z);
|
||||
int8_t z,
|
||||
Necessity = Required);
|
||||
static Resource glyphs(const std::string& urlTemplate,
|
||||
const FontStack& fontStack,
|
||||
const std::pair<uint16_t, uint16_t>& glyphRange);
|
||||
@@ -49,13 +56,14 @@ public:
|
||||
static Resource spriteJSON(const std::string& base, float pixelRatio);
|
||||
|
||||
Kind kind;
|
||||
Necessity necessity;
|
||||
std::string url;
|
||||
|
||||
// Includes auxiliary data if this is a tile request.
|
||||
optional<TileData> tileData;
|
||||
|
||||
optional<SystemTimePoint> priorModified = {};
|
||||
optional<SystemTimePoint> priorExpires = {};
|
||||
optional<Timestamp> priorModified = {};
|
||||
optional<Timestamp> priorExpires = {};
|
||||
optional<std::string> priorEtag = {};
|
||||
};
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ public:
|
||||
// The actual data of the response. Present only for non-error, non-notModified responses.
|
||||
std::shared_ptr<const std::string> data;
|
||||
|
||||
optional<SystemTimePoint> modified;
|
||||
optional<SystemTimePoint> expires;
|
||||
optional<Timestamp> modified;
|
||||
optional<Timestamp> expires;
|
||||
optional<std::string> etag;
|
||||
};
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
namespace mbgl {
|
||||
|
||||
using Clock = std::chrono::steady_clock;
|
||||
using SystemClock = std::chrono::system_clock;
|
||||
|
||||
using Seconds = std::chrono::seconds;
|
||||
using Milliseconds = std::chrono::milliseconds;
|
||||
@@ -15,18 +14,22 @@ using Milliseconds = std::chrono::milliseconds;
|
||||
using TimePoint = Clock::time_point;
|
||||
using Duration = Clock::duration;
|
||||
|
||||
using SystemTimePoint = SystemClock::time_point;
|
||||
using SystemDuration = SystemClock::duration;
|
||||
// Used to measure second-precision times, such as times gathered from HTTP responses.
|
||||
using Timestamp = std::chrono::time_point<std::chrono::system_clock, Seconds>;
|
||||
|
||||
namespace util {
|
||||
|
||||
inline Timestamp now() {
|
||||
return std::chrono::time_point_cast<Seconds>(std::chrono::system_clock::now());
|
||||
}
|
||||
|
||||
// Returns the RFC1123 formatted date. E.g. "Tue, 04 Nov 2014 02:13:24 GMT"
|
||||
std::string rfc1123(SystemTimePoint);
|
||||
std::string rfc1123(Timestamp);
|
||||
|
||||
// YYYY-mm-dd HH:MM:SS e.g. "2015-11-26 16:11:23"
|
||||
std::string iso8601(SystemTimePoint);
|
||||
std::string iso8601(Timestamp);
|
||||
|
||||
SystemTimePoint parseTimePoint(const char *);
|
||||
Timestamp parseTimestamp(const char *);
|
||||
|
||||
// C++17 polyfill
|
||||
template <class Rep, class Period, class = std::enable_if_t<
|
||||
|
||||
@@ -39,7 +39,7 @@ constexpr double MAX_ZOOM = 25.5;
|
||||
constexpr uint64_t DEFAULT_MAX_CACHE_SIZE = 50 * 1024 * 1024;;
|
||||
|
||||
constexpr Duration DEFAULT_FADE_DURATION = Milliseconds(300);
|
||||
constexpr SystemDuration CLOCK_SKEW_RETRY_TIMEOUT = Seconds(30);
|
||||
constexpr Seconds CLOCK_SKEW_RETRY_TIMEOUT { 30 };
|
||||
|
||||
} // namespace util
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ void HTTPRequest::onResponse(jni::JNIEnv& env, int code,
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
response.modified = util::parseTimePoint(jni::Make<std::string>(env, modified).c_str());
|
||||
response.modified = util::parseTimestamp(jni::Make<std::string>(env, modified).c_str());
|
||||
}
|
||||
|
||||
if (cacheControl) {
|
||||
@@ -118,7 +118,7 @@ void HTTPRequest::onResponse(jni::JNIEnv& env, int code,
|
||||
}
|
||||
|
||||
if (expires) {
|
||||
response.expires = util::parseTimePoint(jni::Make<std::string>(env, expires).c_str());
|
||||
response.expires = util::parseTimestamp(jni::Make<std::string>(env, expires).c_str());
|
||||
}
|
||||
|
||||
if (code == 200) {
|
||||
|
||||
@@ -271,12 +271,12 @@ std::unique_ptr<AsyncRequest> HTTPFileSource::request(const Resource& resource,
|
||||
|
||||
NSString *expires = [headers objectForKey:@"Expires"];
|
||||
if (expires) {
|
||||
response.expires = util::parseTimePoint([expires UTF8String]);
|
||||
response.expires = util::parseTimestamp([expires UTF8String]);
|
||||
}
|
||||
|
||||
NSString *last_modified = [headers objectForKey:@"Last-Modified"];
|
||||
if (last_modified) {
|
||||
response.modified = util::parseTimePoint([last_modified UTF8String]);
|
||||
response.modified = util::parseTimestamp([last_modified UTF8String]);
|
||||
}
|
||||
|
||||
NSString *etag = [headers objectForKey:@"ETag"];
|
||||
|
||||
@@ -316,7 +316,7 @@ size_t HTTPRequest::headerCallback(char *const buffer, const size_t size, const
|
||||
// Always overwrite the modification date; We might already have a value here from the
|
||||
// Date header, but this one is more accurate.
|
||||
const std::string value { buffer + begin, length - begin - 2 }; // remove \r\n
|
||||
baton->response->modified = SystemClock::from_time_t(curl_getdate(value.c_str(), nullptr));
|
||||
baton->response->modified = Timestamp{ Seconds(curl_getdate(value.c_str(), nullptr)) };
|
||||
} else if ((begin = headerMatches("etag: ", buffer, length)) != std::string::npos) {
|
||||
baton->response->etag = std::string(buffer + begin, length - begin - 2); // remove \r\n
|
||||
} else if ((begin = headerMatches("cache-control: ", buffer, length)) != std::string::npos) {
|
||||
@@ -324,7 +324,7 @@ size_t HTTPRequest::headerCallback(char *const buffer, const size_t size, const
|
||||
baton->response->expires = http::CacheControl::parse(value.c_str()).toTimePoint();
|
||||
} else if ((begin = headerMatches("expires: ", buffer, length)) != std::string::npos) {
|
||||
const std::string value { buffer + begin, length - begin - 2 }; // remove \r\n
|
||||
baton->response->expires = SystemClock::from_time_t(curl_getdate(value.c_str(), nullptr));
|
||||
baton->response->expires = Timestamp{ Seconds(curl_getdate(value.c_str(), nullptr)) };
|
||||
}
|
||||
|
||||
return length;
|
||||
|
||||
@@ -181,7 +181,7 @@ optional<std::pair<Response, uint64_t>> OfflineDatabase::getResource(const Resou
|
||||
Statement accessedStmt = getStatement(
|
||||
"UPDATE resources SET accessed = ?1 WHERE url = ?2");
|
||||
|
||||
accessedStmt->bind(1, SystemClock::now());
|
||||
accessedStmt->bind(1, util::now());
|
||||
accessedStmt->bind(2, resource.url);
|
||||
accessedStmt->run();
|
||||
|
||||
@@ -201,8 +201,8 @@ optional<std::pair<Response, uint64_t>> OfflineDatabase::getResource(const Resou
|
||||
uint64_t size = 0;
|
||||
|
||||
response.etag = stmt->get<optional<std::string>>(0);
|
||||
response.expires = stmt->get<optional<SystemTimePoint>>(1);
|
||||
response.modified = stmt->get<optional<SystemTimePoint>>(2);
|
||||
response.expires = stmt->get<optional<Timestamp>>(1);
|
||||
response.modified = stmt->get<optional<Timestamp>>(2);
|
||||
|
||||
optional<std::string> data = stmt->get<optional<std::string>>(3);
|
||||
if (!data) {
|
||||
@@ -229,7 +229,7 @@ bool OfflineDatabase::putResource(const Resource& resource,
|
||||
" expires = ?2 "
|
||||
"WHERE url = ?3 ");
|
||||
|
||||
update->bind(1, SystemClock::now());
|
||||
update->bind(1, util::now());
|
||||
update->bind(2, response.expires);
|
||||
update->bind(3, resource.url);
|
||||
update->run();
|
||||
@@ -257,7 +257,7 @@ bool OfflineDatabase::putResource(const Resource& resource,
|
||||
update->bind(2, response.etag);
|
||||
update->bind(3, response.expires);
|
||||
update->bind(4, response.modified);
|
||||
update->bind(5, SystemClock::now());
|
||||
update->bind(5, util::now());
|
||||
update->bind(8, resource.url);
|
||||
|
||||
if (response.noContent) {
|
||||
@@ -283,7 +283,7 @@ bool OfflineDatabase::putResource(const Resource& resource,
|
||||
insert->bind(3, response.etag);
|
||||
insert->bind(4, response.expires);
|
||||
insert->bind(5, response.modified);
|
||||
insert->bind(6, SystemClock::now());
|
||||
insert->bind(6, util::now());
|
||||
|
||||
if (response.noContent) {
|
||||
insert->bind(7, nullptr);
|
||||
@@ -309,7 +309,7 @@ optional<std::pair<Response, uint64_t>> OfflineDatabase::getTile(const Resource:
|
||||
" AND y = ?5 "
|
||||
" AND z = ?6 ");
|
||||
|
||||
accessedStmt->bind(1, SystemClock::now());
|
||||
accessedStmt->bind(1, util::now());
|
||||
accessedStmt->bind(2, tile.urlTemplate);
|
||||
accessedStmt->bind(3, tile.pixelRatio);
|
||||
accessedStmt->bind(4, tile.x);
|
||||
@@ -341,8 +341,8 @@ optional<std::pair<Response, uint64_t>> OfflineDatabase::getTile(const Resource:
|
||||
uint64_t size = 0;
|
||||
|
||||
response.etag = stmt->get<optional<std::string>>(0);
|
||||
response.expires = stmt->get<optional<SystemTimePoint>>(1);
|
||||
response.modified = stmt->get<optional<SystemTimePoint>>(2);
|
||||
response.expires = stmt->get<optional<Timestamp>>(1);
|
||||
response.modified = stmt->get<optional<Timestamp>>(2);
|
||||
|
||||
optional<std::string> data = stmt->get<optional<std::string>>(3);
|
||||
if (!data) {
|
||||
@@ -373,7 +373,7 @@ bool OfflineDatabase::putTile(const Resource::TileData& tile,
|
||||
" AND y = ?6 "
|
||||
" AND z = ?7 ");
|
||||
|
||||
update->bind(1, SystemClock::now());
|
||||
update->bind(1, util::now());
|
||||
update->bind(2, response.expires);
|
||||
update->bind(3, tile.urlTemplate);
|
||||
update->bind(4, tile.pixelRatio);
|
||||
@@ -407,7 +407,7 @@ bool OfflineDatabase::putTile(const Resource::TileData& tile,
|
||||
update->bind(1, response.modified);
|
||||
update->bind(2, response.etag);
|
||||
update->bind(3, response.expires);
|
||||
update->bind(4, SystemClock::now());
|
||||
update->bind(4, util::now());
|
||||
update->bind(7, tile.urlTemplate);
|
||||
update->bind(8, tile.pixelRatio);
|
||||
update->bind(9, tile.x);
|
||||
@@ -440,7 +440,7 @@ bool OfflineDatabase::putTile(const Resource::TileData& tile,
|
||||
insert->bind(6, response.modified);
|
||||
insert->bind(7, response.etag);
|
||||
insert->bind(8, response.expires);
|
||||
insert->bind(9, SystemClock::now());
|
||||
insert->bind(9, util::now());
|
||||
|
||||
if (response.noContent) {
|
||||
insert->bind(10, nullptr);
|
||||
|
||||
@@ -30,7 +30,7 @@ public:
|
||||
~OnlineFileRequest();
|
||||
|
||||
void networkIsReachableAgain();
|
||||
void schedule(optional<SystemTimePoint> expires);
|
||||
void schedule(optional<Timestamp> expires);
|
||||
void completed(Response);
|
||||
|
||||
OnlineFileSource::Impl& impl;
|
||||
@@ -192,7 +192,7 @@ OnlineFileRequest::OnlineFileRequest(const Resource& resource_, Callback callbac
|
||||
if (resource.priorExpires) {
|
||||
schedule(resource.priorExpires);
|
||||
} else {
|
||||
schedule(SystemClock::now());
|
||||
schedule(util::now());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,20 +214,20 @@ static Duration errorRetryTimeout(Response::Error::Reason failedRequestReason, u
|
||||
}
|
||||
}
|
||||
|
||||
static Duration expirationTimeout(optional<SystemTimePoint> expires, uint32_t expiredRequests) {
|
||||
static Duration expirationTimeout(optional<Timestamp> expires, uint32_t expiredRequests) {
|
||||
if (expiredRequests) {
|
||||
return Seconds(1 << std::min(expiredRequests - 1, 31u));
|
||||
} else if (expires) {
|
||||
return std::max(SystemDuration::zero(), *expires - SystemClock::now());
|
||||
return std::max(Seconds::zero(), *expires - util::now());
|
||||
} else {
|
||||
return Duration::max();
|
||||
}
|
||||
}
|
||||
|
||||
SystemTimePoint interpolateExpiration(const SystemTimePoint& current,
|
||||
optional<SystemTimePoint> prior,
|
||||
bool& expired) {
|
||||
auto now = SystemClock::now();
|
||||
Timestamp interpolateExpiration(const Timestamp& current,
|
||||
optional<Timestamp> prior,
|
||||
bool& expired) {
|
||||
auto now = util::now();
|
||||
if (current > now) {
|
||||
return current;
|
||||
}
|
||||
@@ -256,10 +256,10 @@ SystemTimePoint interpolateExpiration(const SystemTimePoint& current,
|
||||
// Assume that either the client or server clock is wrong and
|
||||
// try to interpolate a valid expiration date (from the client POV)
|
||||
// observing a minimum timeout.
|
||||
return now + std::max<SystemDuration>(delta, util::CLOCK_SKEW_RETRY_TIMEOUT);
|
||||
return now + std::max<Seconds>(delta, util::CLOCK_SKEW_RETRY_TIMEOUT);
|
||||
}
|
||||
|
||||
void OnlineFileRequest::schedule(optional<SystemTimePoint> expires) {
|
||||
void OnlineFileRequest::schedule(optional<Timestamp> expires) {
|
||||
if (request) {
|
||||
// There's already a request in progress; don't start another one.
|
||||
return;
|
||||
@@ -339,7 +339,7 @@ void OnlineFileRequest::networkIsReachableAgain() {
|
||||
// We need all requests to fail at least once before we are going to start retrying
|
||||
// them, and we only immediately restart request that failed due to connection issues.
|
||||
if (failedRequestReason == Response::Error::Reason::Connection) {
|
||||
schedule(SystemClock::now());
|
||||
schedule(util::now());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -218,7 +218,9 @@ void Statement::bindBlob(int offset, const std::vector<uint8_t>& value, bool ret
|
||||
bindBlob(offset, value.data(), value.size(), retain);
|
||||
}
|
||||
|
||||
template <> void Statement::bind(int offset, std::chrono::system_clock::time_point value) {
|
||||
template <>
|
||||
void Statement::bind(
|
||||
int offset, std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds> value) {
|
||||
assert(stmt);
|
||||
check(sqlite3_bind_int64(stmt, offset, std::chrono::system_clock::to_time_t(value)));
|
||||
}
|
||||
@@ -231,7 +233,10 @@ template <> void Statement::bind(int offset, optional<std::string> value) {
|
||||
}
|
||||
}
|
||||
|
||||
template <> void Statement::bind(int offset, optional<std::chrono::system_clock::time_point> value) {
|
||||
template <>
|
||||
void Statement::bind(
|
||||
int offset,
|
||||
optional<std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>> value) {
|
||||
if (!value) {
|
||||
bind(offset, nullptr);
|
||||
} else {
|
||||
@@ -283,9 +288,12 @@ template <> std::vector<uint8_t> Statement::get(int offset) {
|
||||
return { begin, end };
|
||||
}
|
||||
|
||||
template <> std::chrono::system_clock::time_point Statement::get(int offset) {
|
||||
template <>
|
||||
std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>
|
||||
Statement::get(int offset) {
|
||||
assert(stmt);
|
||||
return std::chrono::system_clock::from_time_t(sqlite3_column_int64(stmt, offset));
|
||||
return std::chrono::time_point_cast<std::chrono::seconds>(
|
||||
std::chrono::system_clock::from_time_t(sqlite3_column_int64(stmt, offset)));
|
||||
}
|
||||
|
||||
template <> optional<int64_t> Statement::get(int offset) {
|
||||
@@ -315,12 +323,15 @@ template <> optional<std::string> Statement::get(int offset) {
|
||||
}
|
||||
}
|
||||
|
||||
template <> optional<std::chrono::system_clock::time_point> Statement::get(int offset) {
|
||||
template <>
|
||||
optional<std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>>
|
||||
Statement::get(int offset) {
|
||||
assert(stmt);
|
||||
if (sqlite3_column_type(stmt, offset) == SQLITE_NULL) {
|
||||
return optional<std::chrono::system_clock::time_point>();
|
||||
return {};
|
||||
} else {
|
||||
return get<std::chrono::system_clock::time_point>(offset);
|
||||
return get<std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>>(
|
||||
offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,14 +79,16 @@ NAN_METHOD(NodeRequest::Respond) {
|
||||
if (Nan::Has(res, Nan::New("modified").ToLocalChecked()).FromJust()) {
|
||||
const double modified = Nan::Get(res, Nan::New("modified").ToLocalChecked()).ToLocalChecked()->ToNumber()->Value();
|
||||
if (!std::isnan(modified)) {
|
||||
response.modified = mbgl::SystemClock::from_time_t(modified / 1000);
|
||||
response.modified = mbgl::Timestamp{ mbgl::Seconds(
|
||||
static_cast<mbgl::Seconds::rep>(modified / 1000)) };
|
||||
}
|
||||
}
|
||||
|
||||
if (Nan::Has(res, Nan::New("expires").ToLocalChecked()).FromJust()) {
|
||||
const double expires = Nan::Get(res, Nan::New("expires").ToLocalChecked()).ToLocalChecked()->ToNumber()->Value();
|
||||
if (!std::isnan(expires)) {
|
||||
response.expires = mbgl::SystemClock::from_time_t(expires / 1000);
|
||||
response.expires = mbgl::Timestamp{ mbgl::Seconds(
|
||||
static_cast<mbgl::Seconds::rep>(expires / 1000)) };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,13 +71,13 @@ void HTTPRequest::handleNetworkReply(QNetworkReply *reply)
|
||||
QString header = QString(line.first).toLower();
|
||||
|
||||
if (header == "last-modified") {
|
||||
response.modified = util::parseTimePoint(line.second.constData());
|
||||
response.modified = util::parseTimestamp(line.second.constData());
|
||||
} else if (header == "etag") {
|
||||
response.etag = std::string(line.second.constData(), line.second.size());
|
||||
} else if (header == "cache-control") {
|
||||
response.expires = http::CacheControl::parse(line.second.constData()).toTimePoint();
|
||||
} else if (header == "expires") {
|
||||
response.expires = util::parseTimePoint(line.second.constData());
|
||||
response.expires = util::parseTimestamp(line.second.constData());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,11 @@
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
DebugBucket::DebugBucket(const OverscaledTileID& id, const TileData::State state_, optional<SystemTimePoint> modified_, optional<SystemTimePoint> expires_, MapDebugOptions debugMode_)
|
||||
DebugBucket::DebugBucket(const OverscaledTileID& id,
|
||||
const TileData::State state_,
|
||||
optional<Timestamp> modified_,
|
||||
optional<Timestamp> expires_,
|
||||
MapDebugOptions debugMode_)
|
||||
: state(state_),
|
||||
modified(std::move(modified_)),
|
||||
expires(std::move(expires_)),
|
||||
|
||||
@@ -18,16 +18,16 @@ class GLObjectStore;
|
||||
class DebugBucket : private util::noncopyable {
|
||||
public:
|
||||
DebugBucket(const OverscaledTileID& id, TileData::State,
|
||||
optional<SystemTimePoint> modified,
|
||||
optional<SystemTimePoint> expires,
|
||||
optional<Timestamp> modified,
|
||||
optional<Timestamp> expires,
|
||||
MapDebugOptions);
|
||||
|
||||
void drawLines(PlainShader&, gl::GLObjectStore&);
|
||||
void drawPoints(PlainShader&, gl::GLObjectStore&);
|
||||
|
||||
const TileData::State state;
|
||||
const optional<SystemTimePoint> modified;
|
||||
const optional<SystemTimePoint> expires;
|
||||
const optional<Timestamp> modified;
|
||||
const optional<Timestamp> expires;
|
||||
const MapDebugOptions debugMode;
|
||||
|
||||
private:
|
||||
|
||||
@@ -48,7 +48,12 @@ Resource Resource::glyphs(const std::string& urlTemplate, const FontStack& fontS
|
||||
};
|
||||
}
|
||||
|
||||
Resource Resource::tile(const std::string& urlTemplate, float pixelRatio, int32_t x, int32_t y, int8_t z) {
|
||||
Resource Resource::tile(const std::string& urlTemplate,
|
||||
float pixelRatio,
|
||||
int32_t x,
|
||||
int32_t y,
|
||||
int8_t z,
|
||||
Necessity necessity) {
|
||||
bool supportsRatio = urlTemplate.find("{ratio}") != std::string::npos;
|
||||
return Resource {
|
||||
Resource::Kind::Tile,
|
||||
@@ -76,7 +81,8 @@ Resource Resource::tile(const std::string& urlTemplate, float pixelRatio, int32_
|
||||
x,
|
||||
y,
|
||||
z
|
||||
}
|
||||
},
|
||||
necessity
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@ public:
|
||||
|
||||
using Callback = std::function<void (std::exception_ptr,
|
||||
std::unique_ptr<GeometryTile>,
|
||||
optional<SystemTimePoint> modified,
|
||||
optional<SystemTimePoint> expires)>;
|
||||
optional<Timestamp> modified,
|
||||
optional<Timestamp> expires)>;
|
||||
/*
|
||||
* Monitor the tile held by this object for changes. When the tile is loaded for the first time,
|
||||
* or updates, the callback is executed. If an error occurs, the first parameter will be set.
|
||||
|
||||
@@ -107,8 +107,8 @@ public:
|
||||
void dumpDebugLogs() const;
|
||||
|
||||
const OverscaledTileID id;
|
||||
optional<SystemTimePoint> modified;
|
||||
optional<SystemTimePoint> expires;
|
||||
optional<Timestamp> modified;
|
||||
optional<Timestamp> expires;
|
||||
|
||||
// Contains the tile ID string for painting debug information.
|
||||
std::unique_ptr<DebugBucket> debugBucket;
|
||||
|
||||
@@ -31,8 +31,8 @@ VectorTileData::VectorTileData(const OverscaledTileID& id_,
|
||||
state = State::loading;
|
||||
tileRequest = monitor->monitorTile([callback, this](std::exception_ptr err,
|
||||
std::unique_ptr<GeometryTile> tile,
|
||||
optional<SystemTimePoint> modified_,
|
||||
optional<SystemTimePoint> expires_) {
|
||||
optional<Timestamp> modified_,
|
||||
optional<Timestamp> expires_) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
|
||||
@@ -11,8 +11,8 @@ static const char *week[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
|
||||
static const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||
|
||||
std::string rfc1123(SystemTimePoint timePoint) {
|
||||
std::time_t time = SystemClock::to_time_t(timePoint);
|
||||
std::string rfc1123(Timestamp timestamp) {
|
||||
std::time_t time = std::chrono::system_clock::to_time_t(timestamp);
|
||||
std::tm info;
|
||||
gmtime_r(&time, &info);
|
||||
char buffer[30];
|
||||
@@ -21,8 +21,8 @@ std::string rfc1123(SystemTimePoint timePoint) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
std::string iso8601(SystemTimePoint timePoint) {
|
||||
std::time_t time = SystemClock::to_time_t(timePoint);
|
||||
std::string iso8601(Timestamp timestamp) {
|
||||
std::time_t time = std::chrono::system_clock::to_time_t(timestamp);
|
||||
std::tm info;
|
||||
gmtime_r(&time, &info);
|
||||
char buffer[30];
|
||||
@@ -30,8 +30,8 @@ std::string iso8601(SystemTimePoint timePoint) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
SystemTimePoint parseTimePoint(const char * timePoint) {
|
||||
return SystemClock::from_time_t(parse_date(timePoint));
|
||||
Timestamp parseTimestamp(const char* timestamp) {
|
||||
return std::chrono::time_point_cast<Seconds>(std::chrono::system_clock::from_time_t(parse_date(timestamp)));
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
|
||||
@@ -25,12 +25,8 @@ CacheControl CacheControl::parse(const std::string& value) {
|
||||
return result;
|
||||
}
|
||||
|
||||
optional<SystemTimePoint> CacheControl::toTimePoint() const {
|
||||
// Round trip through time_t to truncate fractional seconds.
|
||||
return maxAge
|
||||
? SystemClock::from_time_t(SystemClock::to_time_t(
|
||||
SystemClock::now() + std::chrono::seconds(*maxAge)))
|
||||
: optional<SystemTimePoint>();
|
||||
optional<Timestamp> CacheControl::toTimePoint() const {
|
||||
return maxAge ? util::now() + Seconds(*maxAge) : optional<Timestamp>{};
|
||||
}
|
||||
|
||||
} // namespace http
|
||||
|
||||
@@ -16,7 +16,7 @@ public:
|
||||
optional<uint64_t> maxAge;
|
||||
bool mustRevalidate = false;
|
||||
|
||||
optional<SystemTimePoint> toTimePoint() const;
|
||||
optional<Timestamp> toTimePoint() const;
|
||||
};
|
||||
|
||||
} // namespace http
|
||||
|
||||
@@ -22,7 +22,7 @@ TEST(Map, Offline) {
|
||||
auto expiredItem = [] (const std::string& path) {
|
||||
Response response;
|
||||
response.data = std::make_shared<std::string>(util::read_file("test/fixtures/map/offline/"s + path));
|
||||
response.expires = SystemClock::from_time_t(0);
|
||||
response.expires = Timestamp{ Seconds(0) };
|
||||
return response;
|
||||
};
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheRevalidateModified)) {
|
||||
ASSERT_TRUE(res.data.get());
|
||||
EXPECT_EQ("Response", *res.data);
|
||||
EXPECT_FALSE(bool(res.expires));
|
||||
EXPECT_EQ(SystemClock::from_time_t(1420070400), *res.modified);
|
||||
EXPECT_EQ(Timestamp{ Seconds(1420070400) }, *res.modified);
|
||||
EXPECT_FALSE(res.etag);
|
||||
|
||||
// Second request returns the cached response, then immediately revalidates.
|
||||
@@ -119,7 +119,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheRevalidateModified)) {
|
||||
EXPECT_TRUE(res2.notModified);
|
||||
ASSERT_FALSE(res2.data.get());
|
||||
EXPECT_TRUE(bool(res2.expires));
|
||||
EXPECT_EQ(SystemClock::from_time_t(1420070400), *res2.modified);
|
||||
EXPECT_EQ(Timestamp{ Seconds(1420070400) }, *res2.modified);
|
||||
EXPECT_FALSE(res2.etag);
|
||||
|
||||
loop.stop();
|
||||
|
||||
@@ -130,8 +130,8 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(ExpiresParsing)) {
|
||||
EXPECT_EQ(nullptr, res.error);
|
||||
ASSERT_TRUE(res.data.get());
|
||||
EXPECT_EQ("Hello World!", *res.data);
|
||||
EXPECT_EQ(SystemClock::from_time_t(1420797926), res.expires);
|
||||
EXPECT_EQ(SystemClock::from_time_t(1420794326), res.modified);
|
||||
EXPECT_EQ(Timestamp{ Seconds(1420797926) }, res.expires);
|
||||
EXPECT_EQ(Timestamp{ Seconds(1420794326) }, res.modified);
|
||||
EXPECT_EQ("foo", *res.etag);
|
||||
loop.stop();
|
||||
});
|
||||
@@ -147,7 +147,7 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(CacheControlParsing)) {
|
||||
EXPECT_EQ(nullptr, res.error);
|
||||
ASSERT_TRUE(res.data.get());
|
||||
EXPECT_EQ("Hello World!", *res.data);
|
||||
EXPECT_GT(Seconds(2), util::abs(*res.expires - SystemClock::now() - Seconds(120))) << "Expiration date isn't about 120 seconds in the future";
|
||||
EXPECT_GT(Seconds(2), util::abs(*res.expires - util::now() - Seconds(120))) << "Expiration date isn't about 120 seconds in the future";
|
||||
EXPECT_FALSE(bool(res.modified));
|
||||
EXPECT_FALSE(bool(res.etag));
|
||||
loop.stop();
|
||||
|
||||
@@ -148,7 +148,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(RetryDelayOnExpiredTile)) {
|
||||
std::unique_ptr<AsyncRequest> req = fs.request(resource, [&](Response res) {
|
||||
counter++;
|
||||
EXPECT_EQ(nullptr, res.error);
|
||||
EXPECT_GT(SystemClock::now(), res.expires);
|
||||
EXPECT_GT(util::now(), res.expires);
|
||||
});
|
||||
|
||||
util::Timer timer;
|
||||
@@ -172,12 +172,12 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(RetryOnClockSkew)) {
|
||||
switch (counter++) {
|
||||
case 0: {
|
||||
EXPECT_EQ(nullptr, res.error);
|
||||
EXPECT_GT(SystemClock::now(), res.expires);
|
||||
EXPECT_GT(util::now(), res.expires);
|
||||
} break;
|
||||
case 1: {
|
||||
EXPECT_EQ(nullptr, res.error);
|
||||
|
||||
auto now = SystemClock::now();
|
||||
auto now = util::now();
|
||||
EXPECT_LT(now + Seconds(40), res.expires) << "Expiration not interpolated to 60s";
|
||||
EXPECT_GT(now + Seconds(80), res.expires) << "Expiration not interpolated to 60s";
|
||||
|
||||
@@ -195,7 +195,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(RespectPriorExpires)) {
|
||||
|
||||
// Very long expiration time, should never arrive.
|
||||
Resource resource1{ Resource::Unknown, "http://127.0.0.1:3000/test" };
|
||||
resource1.priorExpires = SystemClock::now() + Seconds(100000);
|
||||
resource1.priorExpires = util::now() + Seconds(100000);
|
||||
|
||||
std::unique_ptr<AsyncRequest> req1 = fs.request(resource1, [&](Response) {
|
||||
FAIL() << "Should never be called";
|
||||
@@ -210,7 +210,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(RespectPriorExpires)) {
|
||||
|
||||
// Very long expiration time, should never arrive.
|
||||
Resource resource3{ Resource::Unknown, "http://127.0.0.1:3000/test" };
|
||||
resource3.priorExpires = SystemClock::now() + Seconds(100000);
|
||||
resource3.priorExpires = util::now() + Seconds(100000);
|
||||
|
||||
std::unique_ptr<AsyncRequest> req3 = fs.request(resource3, [&](Response) {
|
||||
FAIL() << "Should never be called";
|
||||
|
||||
Reference in New Issue
Block a user