redis.bend relies on unsafe/foreign
raw source on the hub · import bend-kit-redis@0.1.0.2/redis.bend as Redis
Redis and Valkey client: RESP3 over TCP or TLS, with pipelining and a pool. Source: https://github.com/paymog/bend-kit/tree/main/redis
4 imports
import Base import bend-kit-bytes@0.3.1.0/bytes.bend as Bytes import bend-kit-wire@0.4.6.1/wire.bend as Wire import bend-kit-dns@0.6.0.2/dns.bend as Dns
Types
type Val source · line 11 · raw
Type
A RESP3 value (RESP2 replies decode into the same type). Text fields hold the raw bytes of the line. Dict (a RESP3 map) and Attr keep their pairs flat, key then value, as on the wire and in hiredis. Attr holds the attribute pairs, then the reply they annotate, last. Int is a signed 64-bit integer as two's-complement words.
Simple@text:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Val
Error@text:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Val
Int@hi:U32 -> @lo:U32 -> Val
Bulk@data:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Val
Arr@items:List<&1, Val> -> Val
NullVal
Boolean@value:Bool -> Val
Double@text:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Val
BigNum@text:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Val
BulkError@text:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Val
Verbatim@format:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> @text:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Val
Dict@items:List<&1, Val> -> Val
Set@items:List<&1, Val> -> Val
Attr@items:List<&1, Val> -> Val
Push@items:List<&1, Val> -> Val
type E source · line 105 · raw
Type
The output so far, whether every value had a RESP form, and the count of values written.
E@o:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> @ok:Bool -> @n:U32 -> E
type Num source · line 248 · raw
Data
A decimal line: sign, magnitude words, and whether it has 1 to 19 digits.
Num@neg:Bool -> @hi:U32 -> @lo:U32 -> @ok:Bool -> Num
type Frame source · line 307 · raw
Type
An open aggregate: its kind, the items still due, and the items so far, reversed.
Frame@kind:U32 -> @left:U32 -> @xs:List<&1, Val> -> Frame
type St source · line 310 · raw
Type
SHead@i:U32 -> @stack:List<&1, Frame> -> St
SDone@v:Val -> @i:U32 -> @stack:List<&1, Frame> -> St
SOk@v:Val -> @i:U32 -> St
SMoreSt
SBadSt
type Step source · line 318 · raw
Type
One reply and the index after it; More when the bytes end first; Bad when they cannot start a reply.
Reply@v:Val -> @next:U32 -> Step
MoreStep
BadStep
type Reader source · line 638 · raw
Type
Bytes read from the server, and the index of the first byte not yet decoded.
Reader@buf:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> @pos:U32 -> Reader
type Next source · line 657 · raw
Type
Got@v:Val -> Next
WantNext
BrokenNext
type Config source · line 691 · raw
Data
host is a name or a numeric address; TLS checks the certificate against it. Empty user and pass send no AUTH (a pass alone authenticates as "default"); db 0 sends no SELECT. ms bounds each connect and read (0: none).
Config@host:String -> @port:U32 -> @tls:Bool -> @user:String -> @pass:String -> @db:U32 -> @ms:U32 -> Config
type Failure source · line 698 · raw
Type
A failed call closes its connection. Rejected carries the server's error reply to the handshake.
IoFail@code:U32 -> @why:String -> Failure
ClosedFailure
MalformedFailure
Rejected@reply:Val -> Failure
type Conn source · line 705 · raw
Type
key names the pool bucket: TLS, user, host, port, and db.
Conn@tls:Bool -> @sock:Socket -> @rd:Reader -> @key:String -> @ms:U32 -> Conn
type Rd source · line 751 · raw
Type
RNext holds the reader after its last decode attempt; RFail a socket to close.
RNext@tls:Bool -> @sock:Socket -> @key:String -> @ms:U32 -> @r:Pair(Reader, Next) -> Rd
RFail@tls:Bool -> @sock:Socket -> @why:Failure -> Rd
type Pool source · line 977 · raw
Type
Idle connections per key, up to cap per key.
Pool@cap:U32 -> @idle:Map<&1, List<&1, Conn>> -> Pool
Definitions
def kind.tag source · line 29 · raw
@+kind:U32 -> String
Aggregate kinds, in the order of their type bytes below.
def kind.val source · line 42 · raw
@+kind:U32 -> @xs:List<&1, Val> -> Val
def i64.neg source · line 57 · raw
@+hi:U32 -> @+lo:U32 -> Pair(U32, U32)
def u64.div10 source · line 61 · raw
@+hi:U32 -> @+lo:U32 -> Pair(U32, Pair(U32, U32))
The 64-bit (hi, lo) divided by 10, and the remainder, over 16-bit limbs.
def digit.put source · line 68 · raw
@z:Bool -> @+r:U32 -> @acc:String -> String
def u64.show.go source · line 76 · raw
@f:Nat -> @q:Pair(U32, Pair(U32, U32)) -> @acc:String -> @+z:Bool -> String
z is set once the value left to print is zero; 20 digits hold any u64.
def u64.show source · line 87 · raw
@+hi:U32 -> @+lo:U32 -> String
def i64.show.of source · line 90 · raw
@r:Pair(U32, U32) -> @neg:Bool -> String
def i64.show source · line 98 · raw
@+hi:U32 -> @+lo:U32 -> String
def fresh source · line 108 · raw
E
def text source · line 111 · raw
@+s:String -> 0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes
def none source · line 114 · raw
@m:Maybe<&2, U32> -> Bool
def clean.lf source · line 121 · raw
@+cr:Bool -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Maybe<&2, U32>) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Bool)
def clean.cr source · line 125 · raw
@r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Maybe<&2, U32>) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Bool)
def clean source · line 130 · raw
@t:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Bool)
A line has no CR and no LF.
def put source · line 133 · raw
@st:E -> @+head:String -> @body:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> @+good:Bool -> E
def line source · line 137 · raw
@st:E -> @+tag:String -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Bool) -> E
def blob source · line 141 · raw
@st:E -> @+tag:String -> @b:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> E
def verbatim.of source · line 145 · raw
@st:E -> @+tl:U32 -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, U32) -> @t:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> E
def verbatim source · line 149 · raw
@st:E -> @f:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> @t:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> E
def agg.count source · line 154 · raw
@+kind:U32 -> @+n:U32 -> U32
Maps count pairs and need an even count; Attr needs its pairs and one reply.
def agg.ok source · line 157 · raw
@+kind:U32 -> @+n:U32 -> Bool
def agg source · line 161 · raw
@st:E -> @+kind:U32 -> @sub:E -> E
def boolean source · line 167 · raw
@v:Bool -> String
def enc source · line 174 · raw
@xs:List<&1, Val> -> @st:E -> E
def encode.done source · line 209 · raw
@st:E -> Maybe<&1, 0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes>
def encode source · line 219 · raw
@v:Val -> Maybe<&1, 0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes>
None when a line value holds CR or LF, a Dict has an odd item count, an Attr an even one, or a Verbatim format is not 3 bytes.
def bulks source · line 222 · raw
@xs:List<&1, 0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes> -> List<&1, Val>
def encode.command.done source · line 229 · raw
@st:E -> 0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes
def encode.command source · line 234 · raw
@args:List<&1, 0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes> -> 0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes
A command as a RESP array of bulk strings, the form every server accepts.
def args source · line 238 · raw
@xs:List<&2, String> -> List<&1, 0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes>
Byte-string arguments (one Char per octet) as Bytes.
def num.go source · line 252 · raw
@n:Nat -> @r:Pair(Array<U32>, U32) -> @+i:U32 -> @+hi:U32 -> @+lo:U32 -> @+ok:Bool -> Pair(Array<U32>, Pair(U32, Pair(U32, Bool)))
n digits from i: (hi, lo) = (hi, lo) * 10 + d over 16-bit limbs. 19 digits stay below 2^64.
def num.fin source · line 264 · raw
@+neg:Bool -> @+len:U32 -> @r:Pair(Array<U32>, Pair(U32, Pair(U32, Bool))) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Num)
def num.digits source · line 268 · raw
@+neg:Bool -> @a:Array<U32> -> @+len:U32 -> @+s:U32 -> @+e:U32 -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Num)
def num.sign source · line 272 · raw
@+len:U32 -> @+s:U32 -> @+e:U32 -> @r:Pair(Array<U32>, U32) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Num)
def num source · line 278 · raw
@b:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> @+s:U32 -> @+e:U32 -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Num)
Bytes s until e, which are before len.
def int.mk source · line 282 · raw
@r:Pair(U32, U32) -> Val
def int.val source · line 286 · raw
@good:Bool -> @+neg:Bool -> @+hi:U32 -> @+lo:U32 -> Maybe<&1, Val>
def int.of source · line 294 · raw
@n:Num -> Maybe<&1, Val>
RESP integers are signed 64-bit: the magnitude may reach 2^63 only when negative.
def len.of source · line 300 · raw
@n:Num -> U32
A length or count below 2^31; -1 (RESP2 null) is 4294967295 and anything else is 4294967294.
def byte.of source · line 323 · raw
@r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Maybe<&2, U32>) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, U32)
def byte source · line 332 · raw
@b:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> @+i:U32 -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, U32)
Byte i, or 256 past the end.
def known source · line 335 · raw
@+t:U32 -> Bool
def null.st source · line 370 · raw
@ok:Bool -> @+next:U32 -> @stack:List<&1, Frame> -> St
def line.val source · line 377 · raw
@+k:U32 -> @t:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Val
def line.st source · line 388 · raw
@+k:U32 -> @+next:U32 -> @stack:List<&1, Frame> -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, 0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
def int.done source · line 392 · raw
@m:Maybe<&1, Val> -> @+next:U32 -> @stack:List<&1, Frame> -> St
def int.st source · line 399 · raw
@+next:U32 -> @stack:List<&1, Frame> -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Num) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
def boolean.done source · line 403 · raw
@ok:Bool -> @+v:Bool -> @+next:U32 -> @stack:List<&1, Frame> -> St
def boolean.st source · line 410 · raw
@+next:U32 -> @stack:List<&1, Frame> -> @+one:Bool -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, U32) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
def blob.mk source · line 414 · raw
@+kind:U32 -> @d:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Val
def blob.done source · line 421 · raw
@+kind:U32 -> @+after:U32 -> @stack:List<&1, Frame> -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, 0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
def verb.text source · line 425 · raw
@f:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> @+after:U32 -> @stack:List<&1, Frame> -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, 0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
def verb.fmt source · line 429 · raw
@+n:U32 -> @+next:U32 -> @stack:List<&1, Frame> -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, 0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
def verb.ok source · line 433 · raw
@ok:Bool -> @+n:U32 -> @+next:U32 -> @stack:List<&1, Frame> -> @b:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
def verb.colon source · line 440 · raw
@+n:U32 -> @+next:U32 -> @stack:List<&1, Frame> -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, U32) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
def verb.len source · line 445 · raw
@ok:Bool -> @+n:U32 -> @+next:U32 -> @stack:List<&1, Frame> -> @b:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
A verbatim string is a 3-byte format, a colon, then the text.
def blob.val source · line 452 · raw
@+kind:U32 -> @+n:U32 -> @+next:U32 -> @stack:List<&1, Frame> -> @b:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
def blob.crlf source · line 459 · raw
@+kind:U32 -> @+n:U32 -> @+next:U32 -> @stack:List<&1, Frame> -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Bool) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
def crlf.at source · line 467 · raw
@b:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> @+j:U32 -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Bool)
def blob.fit source · line 471 · raw
@ok:Bool -> @+kind:U32 -> @+n:U32 -> @+next:U32 -> @stack:List<&1, Frame> -> @b:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
def blob.room source · line 478 · raw
@+kind:U32 -> @+n:U32 -> @+next:U32 -> @stack:List<&1, Frame> -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, U32) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
def blob.bad source · line 482 · raw
@bad:Bool -> @+kind:U32 -> @+n:U32 -> @+next:U32 -> @stack:List<&1, Frame> -> @b:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
def blob.nil source · line 490 · raw
@nil:Bool -> @+kind:U32 -> @+n:U32 -> @+next:U32 -> @stack:List<&1, Frame> -> @b:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
$-1 is RESP2's null bulk string; ! and = have no null form.
def blob.st source · line 498 · raw
@+kind:U32 -> @+next:U32 -> @stack:List<&1, Frame> -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Num) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
kind 0 is $, 1 is !, 2 is =.
def agg.open source · line 503 · raw
@empty:Bool -> @+kind:U32 -> @+left:U32 -> @+next:U32 -> @stack:List<&1, Frame> -> St
def agg.left source · line 511 · raw
@+kind:U32 -> @+n:U32 -> U32
A map of n pairs has 2n items; an attribute adds the reply after its pairs.
def agg.bad source · line 514 · raw
@bad:Bool -> @+kind:U32 -> @+n:U32 -> @+next:U32 -> @stack:List<&1, Frame> -> St
def agg.nil source · line 523 · raw
@nil:Bool -> @+kind:U32 -> @+n:U32 -> @+next:U32 -> @stack:List<&1, Frame> -> St
*-1 is RESP2's null array.
def agg.st source · line 530 · raw
@+kind:U32 -> @+next:U32 -> @stack:List<&1, Frame> -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Num) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
def item source · line 536 · raw
@+t:U32 -> @+s:U32 -> @+e:U32 -> @b:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> @stack:List<&1, Frame> -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
The type byte t, then the line from s until the CRLF at e.
def head.eol source · line 569 · raw
@+t:U32 -> @+i:U32 -> @stack:List<&1, Frame> -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Maybe<&2, U32>) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
def head.end source · line 577 · raw
@end:Bool -> St
def head.known source · line 584 · raw
@ok:Bool -> @+t:U32 -> @+i:U32 -> @stack:List<&1, Frame> -> @b:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
def head source · line 591 · raw
@+i:U32 -> @stack:List<&1, Frame> -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, U32) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St)
def done.last source · line 595 · raw
@last:Bool -> @+kind:U32 -> @+left:U32 -> @xs:List<&1, Val> -> @+i:U32 -> @rest:List<&1, Frame> -> St
def done source · line 602 · raw
@stack:List<&1, Frame> -> @v:Val -> @+i:U32 -> St
def run source · line 610 · raw
@fuel:Nat -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, St) -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Step)
def decode source · line 631 · raw
@b:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> @+i:U32 -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Step)
One reply starting at byte i of b. Every item takes at least 3 bytes and each step reads an item or closes one, so 2 * (len - i) + 2 steps are enough.
def reader source · line 641 · raw
Reader
def feed.at source · line 644 · raw
@zero:Bool -> @buf:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> @+pos:U32 -> @chunk:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Reader
def feed source · line 653 · raw
@r:Reader -> @chunk:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> Reader
Drops the decoded bytes, then adds chunk. ponytail: a reply split over k reads is decoded from its start k times; keep state per item if huge arrays arrive slowly.
def next.of source · line 662 · raw
@+pos:U32 -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Step) -> Pair(Reader, Next)
def next source · line 673 · raw
@r:Reader -> Pair(Reader, Next)
The next whole reply, Want when it has not all arrived, or Broken for bytes that are not RESP.
def pending.of source · line 677 · raw
@+pos:U32 -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, U32) -> Pair(Reader, U32)
def pending source · line 682 · raw
@r:Reader -> Pair(Reader, U32)
The count of bytes read but not yet decoded.
def config source · line 694 · raw
@+host:String -> @+port:U32 -> Config
def io.close source · line 708 · raw
@tls:Bool -> @s:Socket -> IO(Unit)
def io.send source · line 715 · raw
@tls:Bool -> @s:Socket -> @+len:U32 -> @buf:Array<U32> -> IO(Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>))
def io.recv source · line 722 · raw
@tls:Bool -> @s:Socket -> @+ms:U32 -> IO(Pair(Socket, Result<&1, &1, Pair(U32, String), Pair(U32, Array<U32>)>))
def close source · line 729 · raw
@c:Conn -> IO(Unit)
def send.after source · line 733 · raw
@+tls:Bool -> @rd:Reader -> @+key:String -> @+ms:U32 -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> IO(Result<&1, &1, Failure, Conn>)
def send source · line 743 · raw
@c:Conn -> @data:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> IO(Result<&1, &1, Failure, Conn>)
def got.len source · line 755 · raw
@zero:Bool -> @+tls:Bool -> @+key:String -> @+ms:U32 -> @rd:Reader -> @s:Socket -> @+len:U32 -> @words:Array<U32> -> Rd
def got source · line 762 · raw
@+tls:Bool -> @+key:String -> @+ms:U32 -> @rd:Reader -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Pair(U32, Array<U32>)>) -> Rd
def read.fail source · line 770 · raw
@tls:Bool -> @sock:Socket -> @why:Failure -> IO(Result<&1, &1, Failure, Pair(Conn, Val)>)
def read.loop source · line 776 · raw
@fuel:Nat -> @st:Rd -> IO(Result<&1, &1, Failure, Pair(Conn, Val)>)
One recv per step. 2^24 reads of up to 64 KiB pass Redis's 512 MiB bulk limit.
def read source · line 801 · raw
@c:Conn -> IO(Result<&1, &1, Failure, Pair(Conn, Val)>)
The next reply. Bytes already read are decoded before the socket is asked for more.
def read.push source · line 805 · raw
@xs:List<&1, Val> -> @r:Result<&1, &1, Failure, Pair(Conn, Val)> -> Result<&1, &1, Failure, Pair(Conn, List<&1, Val>)>
def read.n source · line 813 · raw
@n:Nat -> @st:Result<&1, &1, Failure, Pair(Conn, List<&1, Val>)> -> IO(Result<&1, &1, Failure, Pair(Conn, List<&1, Val>)>)
n more replies onto the reversed list in st.
def commands source · line 830 · raw
@cmds:List<&1, List<&1, 0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes>> -> @o:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> @+n:Nat -> Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Nat)
def pipeline.sent source · line 837 · raw
@+n:Nat -> @r:Result<&1, &1, Failure, Conn> -> IO(Result<&1, &1, Failure, Pair(Conn, List<&1, Val>)>)
def pipeline.of source · line 844 · raw
@c:Conn -> @r:Pair(0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes, Nat) -> IO(Result<&1, &1, Failure, Pair(Conn, List<&1, Val>)>)
def pipeline source · line 852 · raw
@c:Conn -> @cmds:List<&1, List<&1, 0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes>> -> IO(Result<&1, &1, Failure, Pair(Conn, List<&1, Val>)>)
Sends every command in one write, then reads one reply per command, in order. Error replies come back as Error or BulkError values, not as failures.
def command.sent source · line 855 · raw
@r:Result<&1, &1, Failure, Conn> -> IO(Result<&1, &1, Failure, Pair(Conn, Val)>)
def command source · line 863 · raw
@c:Conn -> @argv:List<&1, 0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes> -> IO(Result<&1, &1, Failure, Pair(Conn, Val)>)
One command and its reply, for example command(c, args(["SET", "k", "v"])).
def get source · line 868 · raw
@c:Conn -> @key:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> IO(Result<&1, &1, Failure, Pair(Conn, Val)>)
def set source · line 871 · raw
@c:Conn -> @key:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> @value:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> IO(Result<&1, &1, Failure, Pair(Conn, Val)>)
def incr source · line 874 · raw
@c:Conn -> @key:0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes -> IO(Result<&1, &1, Failure, Pair(Conn, Val)>)
def first.err source · line 877 · raw
@xs:List<&1, Val> -> Maybe<&1, Val>
def hello.check source · line 888 · raw
@c:Conn -> @e:Maybe<&1, Val> -> IO(Result<&1, &1, Failure, Conn>)
def hello.got source · line 897 · raw
@r:Result<&1, &1, Failure, Pair(Conn, List<&1, Val>)> -> IO(Result<&1, &1, Failure, Conn>)
def hello.auth source · line 904 · raw
@+user:String -> @+pass:String -> List<&2, String>
def hello.select source · line 907 · raw
@+db:U32 -> List<&1, List<&1, 0xb7603dcfa1d7f60d01e06c928738cc73/bytes.Bytes>>
def hello source · line 911 · raw
@c:Conn -> @+user:String -> @+pass:String -> @+db:U32 -> IO(Result<&1, &1, Failure, Conn>)
HELLO 3 (with AUTH), then SELECT, in one pipeline.
def key source · line 916 · raw
@cfg:Config -> String
def tls.done source · line 920 · raw
@+key:String -> @+ms:U32 -> @+user:String -> @+pass:String -> @+db:U32 -> @m:Pair(Socket, Result<&1, &1, Pair(U32, String), Unit>) -> IO(Result<&1, &1, Failure, Conn>)
def dialed source · line 930 · raw
@r:Result<&1, &1, Pair(U32, String), Socket> -> @tls:Bool -> @+k:String -> @+host:String -> @+user:String -> @+pass:String -> @+db:U32 -> @+ms:U32 -> IO(Result<&1, &1, Failure, Conn>)
def dial.after source · line 943 · raw
@r:Result<&1, &1, Pair(U32, String), Socket> -> @+ip:String -> @+port:U32 -> @+ms:U32 -> IO(Result<&1, &1, Pair(U32, String), Socket>)
def dial.more source · line 950 · raw
@prev:IO(Result<&1, &1, Pair(U32, String), Socket>) -> @+ip:String -> @+port:U32 -> @+ms:U32 -> IO(Result<&1, &1, Pair(U32, String), Socket>)
def dial source · line 956 · raw
@ips:List<&2, String> -> @+port:U32 -> @+ms:U32 -> @acc:IO(Result<&1, &1, Pair(U32, String), Socket>) -> IO(Result<&1, &1, Pair(U32, String), Socket>)
Each address in turn, until one connects.
def connect.to source · line 963 · raw
@+k:String -> @cfg:Config -> IO(Result<&1, &1, Failure, Conn>)
def connect source · line 971 · raw
@+cfg:Config -> IO(Result<&1, &1, Failure, Conn>)
TCP (and TLS, which checks the certificate and host name), then the handshake.
def pool.new.with source · line 980 · raw
@+cap:U32 -> Pool
def pool.new source · line 983 · raw
Pool
def pool.take source · line 986 · raw
@+cap:U32 -> @+k:String -> @r:Pair(Map<&1, List<&1, Conn>>, Maybe<&1, List<&1, Conn>>) -> Pair(Pool, Maybe<&1, Conn>)
def pool.opened source · line 998 · raw
@p:Pool -> @r:Result<&1, &1, Failure, Conn> -> IO(Pair(Pool, Result<&1, &1, Failure, Conn>))
def pool.got source · line 1001 · raw
@cfg:Config -> @r:Pair(Pool, Maybe<&1, Conn>) -> IO(Pair(Pool, Result<&1, &1, Failure, Conn>))
def pool.get source · line 1013 · raw
@p:Pool -> @+cfg:Config -> IO(Pair(Pool, Result<&1, &1, Failure, Conn>))
The idle connection given back last, or a new one. ponytail: an idle connection the server has since closed fails on its first command; add a PING check if that bites.
def conns.cut source · line 1019 · raw
@xs:List<&1, Conn> -> @n:Nat -> IO(List<&1, Conn>)
The first n connections; the rest are closed.
def pool.keep source · line 1034 · raw
@+cap:U32 -> @+k:String -> @c:Conn -> @r:Pair(Map<&1, List<&1, Conn>>, Maybe<&1, List<&1, Conn>>) -> IO(Pool)
def pool.give source · line 1040 · raw
@p:Pool -> @c:Conn -> IO(Pool)
def pool.clean source · line 1045 · raw
@clean:Bool -> @p:Pool -> @c:Conn -> IO(Pool)
def pool.left source · line 1054 · raw
@p:Pool -> @+tls:Bool -> @sock:Socket -> @+key:String -> @+ms:U32 -> @r:Pair(Reader, U32) -> IO(Pool)
def pool.put source · line 1059 · raw
@p:Pool -> @c:Conn -> IO(Pool)
Gives c back for reuse. A connection with unread reply bytes is out of step, so it is closed.
def pool.close.go source · line 1063 · raw
@xs:List<&1, List<&1, Conn>> -> IO(Unit)
def pool.close source · line 1072 · raw
@p:Pool -> IO(Unit)