diff options
author | 2023-08-28 08:38:30 -0700 | |
---|---|---|
committer | 2023-08-28 08:38:30 -0700 | |
commit | a2ddfe6913c1884bfef6314d00cf2b708281ff79 (patch) | |
tree | 88e436313a73d2ab1426ac94be122d62fecb72bc /packages/bun-uws/examples/helpers/AsyncFileReader.h | |
parent | 6e4a1f2918cb4dbcc035d350d6cd9f018ea8df59 (diff) | |
download | bun-a2ddfe6913c1884bfef6314d00cf2b708281ff79.tar.gz bun-a2ddfe6913c1884bfef6314d00cf2b708281ff79.tar.zst bun-a2ddfe6913c1884bfef6314d00cf2b708281ff79.zip |
Bring uSockets & uWebSockets forks into Bun's repository (#4372)
* Move uWebSockets and uSockets forks into Bun's repository
* Update Makefile
* Update settings.json
* Update libuwsockets.cpp
* Remove backends we won't be using
* Update bindings.cpp
---------
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'packages/bun-uws/examples/helpers/AsyncFileReader.h')
-rw-r--r-- | packages/bun-uws/examples/helpers/AsyncFileReader.h | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/packages/bun-uws/examples/helpers/AsyncFileReader.h b/packages/bun-uws/examples/helpers/AsyncFileReader.h new file mode 100644 index 000000000..c086c1e95 --- /dev/null +++ b/packages/bun-uws/examples/helpers/AsyncFileReader.h @@ -0,0 +1,130 @@ +#include <map> +#include <cstring> +#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 + * features instead of this really bad demo */ +struct AsyncFileReader { +private: + /* The cache we have in memory for this file */ + std::string cache; + int cacheOffset; + bool hasCache; + + /* The pending async file read (yes we only support one pending read) */ + std::function<void(std::string_view)> pendingReadCb; + + int fileSize; + std::string fileName; + std::ifstream fin; + uWS::Loop *loop; + +public: + /* Construct a demo async. file reader for fileName */ + AsyncFileReader(std::string fileName) : fileName(fileName) { + fin.open(fileName, std::ios::binary); + + // get fileSize + fin.seekg(0, fin.end); + fileSize = fin.tellg(); + + //std::cout << "File size is: " << fileSize << std::endl; + + // cache up 1 mb! + cache.resize(1024 * 1024); + + //std::cout << "Caching 1 MB at offset = " << 0 << std::endl; + fin.seekg(0, fin.beg); + fin.read(cache.data(), cache.length()); + cacheOffset = 0; + hasCache = true; + + // get loop for thread + + loop = uWS::Loop::get(); + } + + /* Returns any data already cached for this offset */ + std::string_view peek(int offset) { + /* Did we hit the cache? */ + if (hasCache && offset >= cacheOffset && ((offset - cacheOffset) < cache.length())) { + /* Cache hit */ + //std::cout << "Cache hit!" << std::endl; + + /*if (fileSize - offset < cache.length()) { + std::cout << "LESS THAN WHAT WE HAVE!" << std::endl; + }*/ + + int chunkSize = std::min<int>(fileSize - offset, cache.length() - offset + cacheOffset); + + return std::string_view(cache.data() + offset - cacheOffset, chunkSize); + } else { + /* Cache miss */ + //std::cout << "Cache miss!" << std::endl; + return std::string_view(nullptr, 0); + } + } + + /* Asynchronously request more data at offset */ + void request(int offset, std::function<void(std::string_view)> cb) { + + // 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; + } + + // disable cache + hasCache = false; + + std::async(std::launch::async, [this, cb, offset]() { + //std::cout << "ASYNC Caching 1 MB at offset = " << offset << std::endl; + + + + // den har stängts! öppna igen! + if (!fin.good()) { + fin.close(); + //std::cout << "Reopening fin!" << std::endl; + fin.open(fileName, std::ios::binary); + } + fin.seekg(offset, fin.beg); + fin.read(cache.data(), cache.length()); + + cacheOffset = offset; + + loop->defer([this, cb, offset]() { + + int chunkSize = std::min<int>(cache.length(), fileSize - offset); + + // båda dessa sker, wtf? + if (chunkSize == 0) { + std::cout << "Zero size!?" << std::endl; + } + + 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 */ + void abort() { + + } + + int getFileSize() { + return fileSize; + } +}; |