Loop::defer and almost working async streaming

This commit is contained in:
Alex Hultman
2018-09-23 21:48:29 +02:00
parent 2fb87b67c7
commit 8106a0f628
6 changed files with 123 additions and 17 deletions
+37 -9
View File
@@ -3,6 +3,7 @@
#include <fstream>
#include <sstream>
#include <iostream>
#include <future>
/* This is just a very simple and inefficient demo of async responses,
* please do roll your own variant or use a database or Node.js's async
@@ -11,7 +12,8 @@ struct AsyncFileReader {
private:
/* The cache we have in memory for this file */
std::string cache;
int cacheOffset = 0;
int cacheOffset;
bool hasCache;
/* The pending async file read (yes we only support one pending read) */
std::function<void(std::string_view)> pendingReadCb;
@@ -38,6 +40,7 @@ public:
fin.seekg(0, fin.beg);
fin.read(cache.data(), cache.length());
cacheOffset = 0;
hasCache = true;
// get loop for thread
@@ -47,7 +50,7 @@ public:
/* Returns any data already cached for this offset */
std::string_view peek(int offset) {
/* Did we hit the cache? */
if (offset >= cacheOffset && ((offset - cacheOffset) < cache.length())) {
if (hasCache && offset >= cacheOffset && ((offset - cacheOffset) < cache.length())) {
/* Cache hit */
//std::cout << "Cache hit!" << std::endl;
return std::string_view(cache.data() + offset - cacheOffset, cache.length() - offset + cacheOffset);
@@ -61,14 +64,39 @@ public:
/* Asynchronously request more data at offset */
void request(int offset, std::function<void(std::string_view)> cb) {
// std::async this
//std::cout << "Caching 1 MB at offset = " << offset << std::endl;
fin.seekg(offset, fin.beg);
fin.read(cache.data(), cache.length());
cacheOffset = offset;
// in this case, what do we do?
// we need to queue up this chunk request and callback!
// if queue is full, either block or close the connection via abort!
if (!hasCache) {
// already requesting a chunk!
std::cout << "ERROR: already requesting a chunk!" << std::endl;
return;
}
// Loop.defer this
cb(std::string_view(cache.data(), cache.length()));
// disable cache
hasCache = false;
std::async(std::launch::async, [this, cb, offset]() {
std::cout << "ASYNC Caching 1 MB at offset = " << offset << std::endl;
fin.seekg(offset, fin.beg);
fin.read(cache.data(), cache.length());
cacheOffset = offset;
loop->defer([this, cb]() {
int chunkSize = std::min(cache.length(), fileSize - offset);
if (chunkSize != cache.length()) {
std::cout << "LESS THAN A CACHE 1 MB!" << std::endl;
}
hasCache = true;
cb(std::string_view(cache.data(), chunkSize));
});
});
}
/* Abort any pending async. request */