aboutsummaryrefslogtreecommitdiff
path: root/packages/bun-uws/examples/helpers/AsyncFileReader.h
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2023-08-28 08:38:30 -0700
committerGravatar GitHub <noreply@github.com> 2023-08-28 08:38:30 -0700
commita2ddfe6913c1884bfef6314d00cf2b708281ff79 (patch)
tree88e436313a73d2ab1426ac94be122d62fecb72bc /packages/bun-uws/examples/helpers/AsyncFileReader.h
parent6e4a1f2918cb4dbcc035d350d6cd9f018ea8df59 (diff)
downloadbun-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.h130
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;
+ }
+};