memcached client in Factor

It been a while since I mentioned this idea, but here’s an implementation of a memcached client in Factor. It’s not completely robust, but it works well enough. Next up is a server that accepts Factor scripts to execute locally.

USING: kernel io io.crlf io.encodings.ascii io.sockets io.streams.duplex strings sequences splitting math.parser formatting ;
IN: memcached.client

! Based on protocol for memcached v1.2.2

<PRIVATE

: get-response-data ( int -- string )
read read-crlf drop ;

: get-response-header ( string -- int )
" " split fourth string>number ;

! I'm sure there's a better way to do this
: get-response-end ( -- string/f )
read-crlf [ "END" = not ] keep and ;

: get-response ( -- seq )
V{ } [ get-response-end dup ] [ get-response-header get-response-data suffix ] while drop ;

: store-command ( command key value -- string )
[ length ] keep "%s %s 0 0 %d\r\n%s\r\n" sprintf ;

: send ( cmd -- )
write flush ;

: store ( command key value stream -- string )
[ store-command send read-crlf ] with-stream* ;

: retrieve ( str stream -- data )
[ send get-response ] with-stream* ;

: remove ( command stream -- string )
[ send read-crlf ] with-stream* ;

PRIVATE>

! Handling connections

: connect ( ip port -- stream local )
<inet> ascii <client> ;

: disconnect ( stream -- )
drop ;

! Storage commands: set, add, replace

: set ( key data stream -- str )
[ "set" -rot ] dip store ;

: add ( key data stream -- str )
[ "add" -rot ] dip store ;

: replace ( key data stream -- str )
[ "replace" -rot ] dip store ;

! Retrieval commands: get

: get ( key stream -- data )
[ "get %s\r\n" sprintf ] dip retrieve ;

! Deletion commands: delete

: delete ( key stream -- str )
[ "delete %s\r\n" sprintf ] dip remove ;

! Increment/Decrement

: incr ( key val stream -- str )
[ "incr %s %d\r\n" sprintf send read-crlf ] with-stream* ;

: decr ( key val stream -- str )
[ "decr %s %d\r\n" sprintf send read-crlf ] with-stream* ;
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s