Loop::defer and almost working async streaming
This commit is contained in:
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user