-
-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add
experimental/web_streams_connection
module (#405)
`std/io` has been deprecated in [v0.203.0](https://github.com/denoland/deno_std/releases/tag/0.203.0). So, we need to migrate from `Deno.Reader`/`Deno.Writer` to Web Streams API in near future. In preparation for it, this commit experimentally adds support for RESP based on Web Streams API.
- Loading branch information
Showing
54 changed files
with
830 additions
and
262 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,29 @@ | ||
import { run } from "./benchmark.js"; | ||
import { connect } from "../mod.ts"; | ||
import { connect as connectWebStreams } from "../experimental/web_streams_connection/mod.ts"; | ||
|
||
const redis = await connect({ hostname: "127.0.0.1" }); | ||
try { | ||
await run({ | ||
client: redis, | ||
driver: "deno-redis", | ||
}); | ||
} finally { | ||
await redis.quit(); | ||
{ | ||
const redis = await connect({ hostname: "127.0.0.1" }); | ||
try { | ||
await run({ | ||
client: redis, | ||
driver: "deno-redis", | ||
}); | ||
} finally { | ||
await redis.quit(); | ||
} | ||
} | ||
|
||
{ | ||
const redis = await connectWebStreams({ hostname: "127.0.0.1" }); | ||
try { | ||
await run({ | ||
client: redis, | ||
driver: "deno-redis (experimental/web_streams_connection)", | ||
outputFilename: | ||
"deno-redis-with-experimental-web-streams-based-connection", | ||
}); | ||
} finally { | ||
await redis.quit(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { kUnstableCreateProtocol } from "../../internal/symbols.ts"; | ||
import type { RedisConnectOptions } from "../../redis.ts"; | ||
import { connect as _connect } from "../../redis.ts"; | ||
import { Protocol } from "../../protocol/web_streams/mod.ts"; | ||
|
||
function createProtocol(conn: Deno.Conn) { | ||
return new Protocol(conn); | ||
} | ||
|
||
export function connect(options: RedisConnectOptions) { | ||
return _connect({ | ||
...options, | ||
[kUnstableCreateProtocol]: createProtocol, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { concateBytes } from "./concate_bytes.ts"; | ||
|
||
const LF = "\n".charCodeAt(0); | ||
/** | ||
* Wraps `ReadableStream` to provide buffering. Heavily inspired by `deno_std/io/buf_reader.ts`. | ||
* | ||
* {@link https://github.com/denoland/deno_std/blob/0.204.0/io/buf_reader.ts} | ||
*/ | ||
export class BufferedReadableStream { | ||
#reader: ReadableStreamDefaultReader<Uint8Array>; | ||
#buffer: Uint8Array; | ||
constructor(readable: ReadableStream<Uint8Array>) { | ||
// TODO: This class could probably be optimized with a BYOB reader. | ||
this.#reader = readable.getReader(); | ||
this.#buffer = new Uint8Array(0); | ||
} | ||
|
||
async readLine(): Promise<Uint8Array> { | ||
const i = this.#buffer.indexOf(LF); | ||
if (i > -1) { | ||
return this.#consume(i + 1); | ||
} | ||
for (;;) { | ||
await this.#fill(); | ||
const i = this.#buffer.indexOf(LF); | ||
if (i > -1) return this.#consume(i + 1); | ||
} | ||
} | ||
|
||
async readFull(buffer: Uint8Array): Promise<void> { | ||
if (buffer.length <= this.#buffer.length) { | ||
buffer.set(this.#consume(buffer.length)); | ||
return; | ||
} | ||
for (;;) { | ||
await this.#fill(); | ||
if (this.#buffer.length >= buffer.length) break; | ||
} | ||
return this.readFull(buffer); | ||
} | ||
|
||
#consume(n: number): Uint8Array { | ||
const b = this.#buffer.subarray(0, n); | ||
this.#buffer = this.#buffer.subarray(n); | ||
return b; | ||
} | ||
|
||
async #fill() { | ||
const chunk = await this.#reader.read(); | ||
if (chunk.done) { | ||
throw new Deno.errors.BadResource(); | ||
} | ||
const bytes = chunk.value; | ||
this.#buffer = concateBytes(this.#buffer, bytes); | ||
} | ||
} |
Oops, something went wrong.