Skip to content

Commit ab3e2a9

Browse files
authored
Merge pull request #21 from und3f/version-2-release-preparation
Release Preparation
2 parents fe03073 + 3b087d5 commit ab3e2a9

File tree

5 files changed

+138
-1
lines changed

5 files changed

+138
-1
lines changed

.github/workflows/cpan.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ on:
1010
jobs:
1111
build:
1212
uses: PerlToolsTeam/github_workflows/.github/workflows/cpan-test.yml@main
13+
with:
14+
os: '["macos-latest", "ubuntu-latest"]'
1315

1416
coverage:
1517
uses: PerlToolsTeam/github_workflows/.github/workflows/cpan-coverage.yml@main

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ MANIFEST*
1010
pm_to_blib
1111
inc/
1212
MYMETA.*
13+
/Protocol-Redis*.tar.gz

Changes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
This file documents the revision history for Perl extension Protocol::Redis
22

3+
2.0000 18.01.2026 00:00:00
4+
- Add support for RESP2 and RESP3 versions (Grinnz).
5+
36
1.0021 03.09.2024 00:00:00
47
- Test unknown version excaption implementation
58

README.pod

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,63 @@ Protocol::Redis - Redis protocol parser/encoder with asynchronous capabilities.
2929
{type => '+', data => 'OK'}
3030
]});
3131

32+
# RESP3 supported with api 3 specified
33+
my $redis = Protocol::Redis->new(api => 3);
34+
35+
print $redis->encode({type => '%', data => {
36+
null => {type => '_', data => undef},
37+
bignum => {type => '(', data => '3492890328409238509324850943850943825024385'},
38+
string => {type => '$', data => 'this is a string'},
39+
# format prepended to verbatim strings (defaults to txt)
40+
verbatim => {type => '=', data => '*verbatim* string', format => 'mkd'},
41+
# set is unordered but specified as array
42+
booleans => {type => '~', data => [
43+
{type => '#', data => 1},
44+
{type => '#', data => 0},
45+
]},
46+
# map is hashlike but can be specified as an
47+
# (even-sized) array to encode non-string keys
48+
special_map => {type => '%', data => [
49+
{type => ':', data => 42} => {type => '$', data => 'The answer'},
50+
{type => '_'} => {type => '$', data => 'No data'},
51+
]},
52+
}, attributes => {
53+
coordinates => {type => '*', data => [
54+
{type => ',', data => '36.001516'},
55+
{type => ',', data => '-78.943319'},
56+
]},
57+
});
58+
59+
# "|1\r\n\$11\r\ncoordinates\r\n*2\r\n,36.001516\r\n,-78.943319\r\n" .
60+
# "%6\r\n" .
61+
# "\$6\r\nbignum\r\n(3492890328409238509324850943850943825024385\r\n" .
62+
# "\$8\r\nbooleans\r\n~2\r\n#t\r\n#f\r\n" .
63+
# "\$4\r\nnull\r\n_\r\n" .
64+
# "\$11\r\nspecial_map\r\n%2\r\n:42\r\n\$10\r\nThe answer\r\n_\r\n\$7\r\nNo data\r\n" .
65+
# "\$6\r\nstring\r\n\$16\r\nthis is a string\r\n" .
66+
# "\$8\r\nverbatim\r\n=21\r\nmkd:*verbatim* string\r\n"
67+
68+
# sets represented in the protocol the same as arrays
69+
# remapping into a hash may be useful to access string set elements
70+
$redis->parse("~3\r\n+x\r\n+y\r\n+z\r\n");
71+
my %set = map {($_->{data} => 1)} @{$redis->get_message->{data}};
72+
die unless exists $set{x};
73+
print join ',', keys %set; # x,y,z in unspecified order
74+
75+
# verbatim strings are prefixed by a format
76+
# this will be returned as the format key
77+
$redis->parse("=16\r\nmkd:* one\n* two\n\r\n");
78+
my $verbatim = $redis->get_message;
79+
die unless $verbatim->{format} eq 'mkd';
80+
print $verbatim->{data};
81+
# * one
82+
# * two
83+
84+
# attributes are maps that apply to the following value
85+
$redis->parse("|1\r\n+hits\r\n:6\r\n\$4\r\nterm\r\n");
86+
my $term = $redis->get_message;
87+
print "$term->{data}: $term->{attributes}{hits}{data}\n";
88+
3289
=head1 DESCRIPTION
3390

3491
Redis protocol parser/encoder with asynchronous capabilities and L<pipelining|http://redis.io/topics/pipelining> support.
@@ -40,6 +97,80 @@ Protocol::Redis APIv1 uses
4097
encoding/parsing and supports methods described further. Client libraries
4198
should specify API version during Protocol::Redis construction.
4299

100+
API version 1 corresponds to the protocol now known as
101+
L<RESP2|https://github.com/redis/redis-specifications/blob/master/protocol/RESP2.md>
102+
and can also thusly be specified as API version 2. It supports the RESP2 data
103+
types C<+-:$*>.
104+
105+
=head1 APIv3
106+
107+
API version 3 supports the same methods as API version 1, corresponding to the
108+
L<RESP3|https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md>
109+
protocol. RESP3 contains support for several additional data types (null,
110+
boolean, double, big number, blob error, verbatim string, map, and set), data
111+
attributes, streamed strings and aggregate data, and explicitly specified push
112+
data so that asynchronous and synchronous responses can share a connection. A
113+
client must request RESP3 support from the server with the HELLO command to use
114+
these features.
115+
116+
APIv3 supports the RESP2 data types C<+-:$*> as well as the RESP3-specific data
117+
types C<< _,#!=(%~|> >>, with the following implementation notes:
118+
119+
=over
120+
121+
=item * Verbatim String
122+
123+
The Verbatim String type, specified with the initial byte C<=>, is treated the
124+
same as the Blob String type C<$> except that the first three bytes specify
125+
the C<format>, followed by a colon C<:>, and the remaining bytes are the string
126+
data. When parsing, the C<format> will be returned as a separate key and not
127+
included in the string C<data>. When encoding, a C<format> can be specified and
128+
otherwise defaults to C<txt>, and will be prepended to the string data.
129+
130+
=item * Big Number
131+
132+
The Big Number type, specified with the initial byte C<(>, is parsed to a
133+
L<Math::BigInt> object, which can be used in numeric or string operations
134+
without losing precision.
135+
136+
=item * Map
137+
138+
The Map type, specified with the initial byte C<%>, is represented in Perl as a
139+
hash. The keys of a Map are allowed to be any data type, but for simplicity
140+
they are coerced to strings as required by Perl hashes, which the specification
141+
allows. When encoding a Map, a hash reference is normally passed, but an array
142+
reference of alternating keys and values may also be passed to allow specifying
143+
non-string keys. If passed as an array, the values will be encoded in the order
144+
specified, but the Map type is defined as unordered.
145+
146+
=item * Attribute
147+
148+
The Attribute type, specified with the initial byte C<|>, is much like the Map
149+
type, but instead of acting as a value in the message, it is applied as the
150+
C<attributes> key of the following value. Like Map, its keys are coerced to
151+
strings as it is represented as a Perl hash.
152+
153+
=item * Set
154+
155+
The Set type, specified with the initial byte C<~>, is represented as an array,
156+
since a Set can contain values of any data type, which native Perl hashes
157+
cannot represent as keys, and the specification does not require enforcing
158+
element uniqueness. If desired, the higher level client and server should
159+
handle deduplication of Set elements, and should also be aware that the type
160+
is defined as unordered and the values are likely to be tested for existence
161+
rather than position.
162+
163+
=item * Push
164+
165+
The Push type, specified with the initial byte C<< > >>, is treated no
166+
differently from an Array, but a client supporting RESP3 must be prepared to
167+
handle a Push value at any time rather than in response to a command. An
168+
asynchronous client would generally execute a predefined callback when a Push
169+
value is received; a synchronous client must also take this into consideration
170+
for how and when it reads messages.
171+
172+
=back
173+
43174
=head2 C<new>
44175

45176
my $redis = Protocol::Redis->new(api => 1);

lib/Protocol/Redis.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use strict;
44
use warnings;
55
use 5.008_001;
66

7-
our $VERSION = '1.0021';
7+
our $VERSION = '2.0000';
88

99
require Carp;
1010

0 commit comments

Comments
 (0)