• Stars
    star
    153
  • Rank 235,763 (Top 5 %)
  • Language
    C
  • License
    Apache License 2.0
  • Created over 7 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Write Redis module in Golang

Go Redis module

go-rm will let you write redis module in golang.

Read in | 中文 | English | Spanish

Modules

Demo

# Ensure you installed the newest redis
# for example by using brew you can
# brew reinstall redis --HEAD

# Build redis module
go build -v -buildmode=c-shared github.com/redismodule/rxhash/cmd/rxhash

# Start redis-server and load our module with debug log
redis-server --loadmodule rxhash --loglevel debug

Connect to out redis-server

# Test hgetset
redis-cli hset a a 1
#> (integer) 1
redis-cli hgetset a a 2
#> "1"
redis-cli hget a a
#> "2"
# Return nil if field not exists
redis-cli hgetset a b 2
#> (nil)
redis-cli hgetset a b 3
#> "2"

Wow, it works, now you can distribute this redis module to you friends. :P

How to write a module

Implement a redis module is as easy as you write a cli app in go, this is all you need to implement above command.

package main

import "github.com/wenerme/go-rm/rm"

func main() {
    // In case someone try to run this
    rm.Run()
}

func init() {
    rm.Mod = CreateMyMod()
}
func CreateMyMod() *rm.Module {
    mod := rm.NewMod()
    mod.Name = "hashex"
    mod.Version = 1
    mod.Commands = []rm.Command{CreateCommand_HGETSET()}
    return mod
}
func CreateCommand_HGETSET() rm.Command {
	return rm.Command{
		Usage: "HGETSET key field value",
		Desc: `Sets the 'field' in Hash 'key' to 'value' and returns the previous value, if any.
Reply: String, the previous value or NULL if 'field' didn't exist. `,
		Name:   "hgetset",
		Flags:  "write fast deny-oom",
		FirstKey:1, LastKey:1, KeyStep:1,
		Action: func(cmd rm.CmdContext) int {
			ctx, args := cmd.Ctx, cmd.Args
			if len(cmd.Args) != 4 {
				return ctx.WrongArity()
			}
			ctx.AutoMemory()
			key, ok := openHashKey(ctx, args[1])
			if !ok {
				return rm.ERR
			}
			// get the current value of the hash element
			var val rm.String;
			key.HashGet(rm.HASH_NONE, cmd.Args[2], (*uintptr)(&val))
			// set the element to the new value
			key.HashSet(rm.HASH_NONE, cmd.Args[2], cmd.Args[3])
			if val.IsNull() {
				ctx.ReplyWithNull()
			} else {
				ctx.ReplyWithString(val)
			}
			return rm.OK
		},
	}
}
// open the key and make sure it is indeed a Hash and not empty
func openHashKey(ctx rm.Ctx, k rm.String) (rm.Key, bool) {
	key := ctx.OpenKey(k, rm.READ | rm.WRITE)
	if key.KeyType() != rm.KEYTYPE_EMPTY && key.KeyType() != rm.KEYTYPE_HASH {
		ctx.ReplyWithError(rm.ERRORMSG_WRONGTYPE)
		return rm.Key(0), false
	}
	return key, true
}

Fantasy

  • A module management module, supplies
    • mod.search
      • Search module from repository(github?)
      • Repository structure like this
      /namespace
          /module-name
              /bin
                  /darwin_amd64
                      module-name.so
                      module-name.sha
                  /linux_amd64
              module-name.go     
      
    • mod.get
      • Download module to ~/.redismodule
      • Because module is write in go, so we can build for almost any platform
      • We can use tag/commit to version the binary, so we can download the old version too
    • mod.install
      • Install downloaded module by calling redis command
    • ...
  • A cluster management module
    • Easy to create/manage/monitor redis3 cluster
  • A json data type to demonstration how to add new data type in redis.
    • json.fmt key template
    • json.path key path [pretty]
    • json.get key [pretty]
    • json.set key value
      • this will validate the json format

Pitfall

  • C can not call Go function, so every callback is pre-generated
    • 200 commands at most
    • 5 data type at most
    • limits are easy to change, just need a proper max value
  • Go can not call var_args, function call is pre-generated
    • HashSet/HashGet can accept 20 args at most
    • limits are easy to change, just need a proper max value
  • Don't know what happens when unload a golang shared module
    • Single module
    • Multi module
      • Is there runtime are shared ?
  • Module write in go can not report it's memory usage to redis, max memory limits is useless
  • If a module write in go also include a third party write in other language, the memory usage is unknown
  • Module can only accept command, seems there is no way to call redis initiative.

TODO

  • Find a proper limits for data types and var_args

More Repositories

1

wener

Notes, Stories, Awesomes
JavaScript
171
star
2

go-wecom

Wechat Work/Wecom/企业微信 Golang SDK
Go
68
star
3

wode

Wener Node, Bun, NestJS, React Utils, Hooks & Demos
TypeScript
35
star
4

astgo

Libs for Go to work with Asterisk
Go
34
star
5

IKAnalyzer

IKAnalyzer 中文分词器
Java
32
star
6

winform.DropShadow

A winform DropShadow demo
C#
25
star
7

alpine-image

AlpineLinux pre-build disk images
Shell
23
star
8

go-req

Declarative golang HTTP client
Go
22
star
9

kube-stub-cluster

Stub for Kubernetes Cluster Deployment by using ArgoCD/Helm/Kustomize
Smarty
16
star
10

bbvm

BeBasic Virtual Machine
Java
15
star
11

charts

HELM Charts Collections
Mustache
14
star
12

dockerfiles

Dockerfiles
Dockerfile
11
star
13

coredns-pdsql

CoreDNS PowerDNS adapter
Go
10
star
14

goaphql

Golang with GraphQL
Go
9
star
15

grpc-protos

A collection of grpc proto
Shell
9
star
16

postjava

Java work with PostgreSQL
Java
8
star
17

myfacility

MySQL facility in GO way
Go
7
star
18

awesome-alpine

A curated list of awesome Alpine linux relates.
6
star
19

apis

TypeScript
6
star
20

dotfiles

Relax dotfiles for Linux, Cygwin & Mac OSX
Shell
6
star
21

wps

Wener's Personal Service
Go
5
star
22

drifter

Flutter plugin work with device
Java
5
star
23

ansible-collection-wenerme-alpine

Ansible collection wener.alpine
Makefile
5
star
24

go-miniquery

SQL Where like filter expression for entql and gorm
Go
5
star
25

scel

Sougou scel dict - 搜狗 scel 词库工具
Go
4
star
26

alpine-admin

Ansible Role for Alpine Host
Python
4
star
27

GTetris

简单的俄罗斯方块, java swing
Java
4
star
28

jraphql

Java with GraphQL
Java
4
star
29

jss

MySQL Protocol Adapter for JDBC Connection
Java
3
star
30

coredns-ipin

CoreDNS plugin resolve the domain to ip in domain name
Go
3
star
31

boltdotnet

mirror for https://boltdotnet.codeplex.com/
C#
3
star
32

QQExportMessageParser

用于解析QQ的导出消息,目前只支持MHT的导出消息,和导出为 SQLit和JSON
C#
3
star
33

vimfiles

My vimfiles
Vim Script
2
star
34

seq

Distributed Sequence Generator
Java
2
star
35

repository

Alpine package repository for newer version or missing pack.
Shell
2
star
36

torrenti

Torrent Indexer
Go
2
star
37

tellets

A way to writing.
Java
2
star
38

node-yarn-starter

Yarn2 with NextJS and Gitlab CI
TypeScript
2
star
39

keycloak-services-cn

Keycloak 中国相关服务集成
Java
2
star
40

stardict

Library/Tools write in golang for Stardict/星际译王
Go
2
star
41

go-magic

libmagic in golang
Go
1
star
42

conlib

一个在控制台下编程的辅助库
C
1
star
43

tools

Index of Tools - ⚙🔩🔧
Go
1
star
44

asp.net.SaySay

我的ASP.NET作业,使用mongodb作为数据库,实现的一个发言的平台,SaySay意为 说说.
JavaScript
1
star
45

islove

IsLove app written in flutter/dart
Dart
1
star
46

go-net

Network for golang
Go
1
star
47

pm-exam-cheatsheet

软考项目管理考试知识整理
TypeScript
1
star
48

mapstruct-extras

MapStruct Extras
Java
1
star
49

go-gb

China GB implemented in Golang / Go 实现中国国家标准
Go
1
star
50

hv-annotation-with-group

Hibernate Validator - Constraint Annotation with Default group
Java
1
star