GitXplorerGitXplorer
g

retcl

public
23 stars
3 forks
1 issues

Commits

List of commits on branch master.
Unverified
18172e5e1ae01a1409e22bd36051613f2aeb6679

Clarify that the two constructor modes (host + port / -noconnect) are distinct

committed 6 months ago
Unverified
5ea77457f5eb73bd15986944e2e342d630702c87

Don't pass a plain "1" to tls::socket and don't use client authentication in ping-pong

committed 7 months ago
Unverified
eb736260bce5bf53547c5b7de135e5ef7a8ec6a2

Release: retcl-0.5.0

committed 8 months ago
Unverified
dc6b065720bcb9b35033b281f0a0c5230fa724ba

Merge tls

committed 8 months ago
Unverified
e5330d84613c60edc8cc1a28db14c1e9142c96fd

Fix typo (thanks to Colin Macleod)

committed 8 months ago
Unverified
4d8f2e8c64e002a9bb29c04d3d25805fa38e58df

Merge trunk

committed 8 months ago

README

The README file for this repository.

ifdef::generate_manpage[] = retcl(n) :author: Pietro Cerutti :email: gahr@gahr.ch :revdate: October 24, 2021 :revnumber: 0.6.0 📦 retcl :doctype: manpage :manmanual: RETCL :mansource: RETCL :man-linkstyle: pass:[blue R<>]

== Name

Retcl - Redis client library for Tcl

== Synopsis

package require *retcl*

*retcl* create _?objectName?_ _?host?_ _?port?_ _?option ...?_

*retcl* create _?objectName?_ -noconnect _?option ...?_

set r [*retcl* new _?host?_ _?port?_]

set r [*retcl* new -noconnect]

*$r* connect _?host?_ _?port?_

*$r* disconnect

*$r* connected

*$r* _?-sync?_ _?-cb?_ _redisCmd_ _?redisArg ...?_

*$r* result _?async?_ _commandId_

*$r* resultReady _commandId_

*$r* resultType _commandId_

*$r* allResults

*$r* clearResult _?commandId?_

*$r* +async

*$r* -async

*$r* ?async

*$r* +tls _?args?_

*$r* -tls

*$r* ?tls

*$r* +keepCache

*$r* -keepCache

*$r* ?keepCache

*$r* errorHandler _?cmdPrefix?_

*$r* pipeline _script_

*$r* callback _item_ _?callback?_

== Description endif::generate_manpage[]

ifndef::generate_manpage[] = retcl: Tcl client library for Redis endif::generate_manpage[]

The retcl module is an event-driven, object-oriented, https://redis.io[Redis] client library for the https://www.tcl-lang.org/[Tcl] programming language. The library exposes a single retcl class, conveniently packaged as a sourceable https://www.tcl-lang.org/man/tcl8.6/TclCmd/tm.htm#M9[Tcl module]. Instances of this class represent connections to a https://redis.io[Redis] server and are used to send requests in the form of native https://redis.io[Redis] commands and retrieve responses.

Other than a few book-keeping methods, retcl instances transparently handle https://redis.io[Redis] commands as first-class methods. As an example, r SET K Hello can be used to set the value of the key K to the string Hello. This is achieved by proxying all unknown methods to the https://redis.io[Redis] server by concatenating all arguments, effectively making retcl instances completely decoupled from any version of Redis. This has several advantages:

  • A retcl instance does not need to know about the semantics of a particular https://redis.io[Redis] command. This includes syntax checks, context verification and arguments validation, which are offloaded to the https://redis.io[Redis] server. As a consequence, the code base remains clean and small.

  • New commands introduced by a server upgrade are immediately available to a live application.

ifndef::generate_manpage[]

[source,tcl]

package require retcl retcl create r r SET key val r -sync GET key ;# val

endif::generate_manpage[]

ifdef::generate_manpage[] == Methods endif::generate_manpage[]

=== Construction

[source,tcl]

set r [retcl new ?host port? ?option ...?] set r [retcl new ?-noconnect? ?option ...?] retcl create r ?host port? ?option ...? retcl create r ?-noconnect? ?option ...?

Create an instance r of retcl. If no host or port is specified, the client automatically connects to localhost on port 6379. If -noconnect is specified, the client is created in disconnected mode. Each additional option is a simple string or a list representing the invocation of a configuration method. Here are some examples. [source,tcl]

retcl create r localhost 6973 -async {+tls -cafile /path/to/ca.crt} retcl create r -keepCache retcl create r -noconnect -keepCache +async

=== Connection / disconnection

[source,tcl]

$r connect ?host? ?port? $r disconnect $r connected

The connect method can be used to connect to a different host and port. It is an error to call this method on an already connected client. The disconnect method can be called no matter the connection status; it disconnects the client from the current host, if any. The connected method can be used to query the current connection status. It returns a true result if the client is connected and a false result otherwise.

=== Interaction with Redis

[source,tcl]

set rid1 [$r SET key val] ;# rid stands for result id $r result $rid1 ;# OK

set rid2 [$r GET key] $r result $rid2 ;# val

$r resultType $rid1 ;# SimpleString $r resultType $rid2 ;# BulkString

$r -sync GET key ;# val

proc mycb {id type body} { puts " id: $id" puts "type: $type" puts "body: $body" }

$r -cb mycb GET key ;# returns immediately and arrange for mycb to be invoked ;# with {rds:1 BulkString val} when the result arrives

As shown in the examples above, the interaction with https://redis.io[Redis] is very straightforwards. Any methods not directly understood by the retcl class are forwarded to the https://redis.io[Redis] server, along with any additional arguments provided. The result is a small string representing a result id. Each call to https://redis.io[Redis] produces a new result id, which can then be queried to inspect its status, type, and value.

By using the -sync switch, it is possible to have https://redis.io[Redis] commands block and only return as soon as the result is available. In this case, the return value is the value returned by https://redis.io[Redis].

By using the -cb switch, it is possible to arrange for a callback procedure to be called whenever the result is ready. In this case, the command returns immediately.

=== Configuration

By default, retcl objects operate in asynchronous mode: they return immediately and produce a result id (rid) that can be inspected later on. The methods -async, +async and ?async can be used to disable, enbale, and query this setting. When the asynchronous behaviour is off, methods wait and return the values returned by https://redis.io[Redis] instead of a result id.

A cache of all results is kept by default. This allows to query previously returned results. The -keepcache, +keepcache, and ?keepcache methods can be used to disable, enable, and query this setting. When the results cache is disabled, results are removed from the cache as soon as they are retrieved by the client.

=== Error handling

A custom error handler can be setup with the errorHandler method. The argument is a command prefix that gets expanded and additioned with an error message string. Passing an empty command prefix resets the error handler to the default error proc.

=== Pipelining

A pipeline can be built with the pipeline method. The argument is a script which gets evaluated in the context of the caller. Commands to the https://redis.io[Redis] server are held for the duration of the script and released as a bulk when the script ends.

=== Publish / subscribe

Publish / subscribe callbacks for specific items can be specified with the callback method. The item argument is a pattern or channel as in PSUBSCRIBE and SUBSCRIBE. The callback argument is a command prefix. Whenever a message arrives on the specific channel, the command prefix is called by appending the type of the message, the pattern that was subscribed to, the actual channel, and the payload.

== TLS

The connection to the https://redis.io[Redis] server is unencrypted by default. If the https://core.tcl-lang.org/tcltls/index[TclTLS] extension is available, the +tls method can be used to enable TLS. The method takes an optional list of arguments that are passed as-is to the [tls::socket] command. In the default configuration, https://redis.io[Redis] requires a valid client certificate on connection, which requires specifying a few parameters, e.g., r +tls -cafile /etc/redis/ca.crt -certfile /etc/redis/redis.crt -keyfile /etc/redis/redis.key. The -tls and ?tls methods can be used to disable and query TLS mode. The link:/retcl/file?name=examples/ping-pong.tcl[ping-pong example] can be run in TLS mode via tclsh ping-pong.tcl --tls.

== Encoding

As per the https://redis.io/docs/latest/develop/reference/protocol-spec/#resp-protocol-description[Redis Serialization Protocol (RESP)], commands are sent over the wire as arrays of bulk strings. Bulk strings contain binary data, so all strings need to be converted to byte streams with values in the range 0-255. Unicode strings need to be encoded in utf-8. See the link:/retcl/file?ln=5&ci=f90952f00ba2ab6d&name=test%2F014-utf8.test[utf8-1.1] test for an example and link:/retcl/tktview/70c08b5b5d[ticket 70c08b5b5dfor] for details.

ifdef::generate_manpage[] == Resources

[%hardbreaks] Project page: https://code.ptrcrt.ch/retcl/

== Copying

Copyright (C) 2014-2018 {author}. Free use of this software is granted under the terms of the BSD-2-Clause License. endif::generate_manpage[]