Skip to content

Commit

Permalink
Merge pull request #21 from Kai-Zhang/master
Browse files Browse the repository at this point in the history
Add python interface
  • Loading branch information
fxsjy committed Sep 14, 2015
2 parents 54dc909 + f4af5fa commit 3624350
Show file tree
Hide file tree
Showing 6 changed files with 497 additions and 2 deletions.
4 changes: 4 additions & 0 deletions COMAKE
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,19 @@ ins_sources = 'server/ins_main.cc server/ins_node_impl.cc server/flags.cc server
ins_sdk_sources = 'sdk/ins_sdk.cc common/logging.cc proto/ins_node.proto server/flags.cc'
ins_sdk_headers = 'sdk/ins_sdk.h'

ins_python_sources = 'sdk/ins_sdk.cc sdk/ins_wrapper.cc common/logging.cc proto/ins_node.proto server/flags.cc'

ins_cli_sources = 'sdk/ins_sdk.cc proto/ins_node.proto common/logging.cc sdk/ins_cli.cc server/flags.cc'
sample_sources = 'sdk/sample.cc'


binlog_test_sources = 'storage/binlog.cc storage/binlog_test.cc common/logging.cc proto/ins_node.proto'
Application('ins', Sources(ins_sources))
Application('ins_cli', Sources(ins_cli_sources))
SharedLibrary('ins_py', Sources(ins_python_sources), LinkDeps(True))
SharedLibrary('ins_sdk', Sources(ins_sdk_sources), LinkDeps(True))
StaticLibrary('ins_sdk', Sources(ins_sdk_sources), HeaderFiles(ins_sdk_headers))
TARGET('py_sdk_copy', ShellCommands('cp sdk/ins_sdk.py output/so/'), Prefixes('libins_py.so'))

Application('binlog_test', Sources(binlog_test_sources))
Application('sample', Sources(sample_sources), Libraries('libins_sdk.a'))
Expand Down
15 changes: 14 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ LDFLAGS = -L$(PREFIX)/lib -L$(PROTOBUF_PATH)/lib \
-L$(LEVELDB_PATH)/lib -lleveldb \
-lz -lpthread

LDFLAGS_SO = -L$(PREFIX)/lib -L$(PROTOBUF_PATH)/lib \
-L$(PBRPC_PATH)/lib -Wl,--whole-archive -lsofa-pbrpc -lprotobuf -Wl,--no-whole-archive \
-L$(SNAPPY_PATH)/lib -lsnappy \
-L$(GFLAGS_PATH)/lib -Wl,--whole-archive -lgflags -Wl,--no-whole-archive \
-L$(LEVELDB_PATH)/lib -lleveldb \
-lz -lpthread

CXXFLAGS += $(OPT)

PROTO_FILE = $(wildcard proto/*.proto)
Expand Down Expand Up @@ -61,6 +68,7 @@ TEST_OBJ = $(patsubst %.cc, %.o, $(TEST_SRC))
TESTS = test_binlog test_storage_manager test_user_manager
BIN = ins ins_cli sample
LIB = libins_sdk.a
PY_LIB = libins_py.so

all: $(BIN) cp $(LIB)

Expand Down Expand Up @@ -90,7 +98,7 @@ $(LIB): $(SDK_OBJ)
$(PROTOC) --proto_path=./proto/ --proto_path=/usr/local/include --cpp_out=./proto/ $<

clean:
rm -rf $(BIN) $(LIB) $(TESTS)
rm -rf $(BIN) $(LIB) $(TESTS) $(PY_LIB)
rm -rf $(INS_OBJ) $(INS_CLI_OBJ) $(SAMPLE_OBJ) $(SDK_OBJ) $(TEST_OBJ) $(UTIL_OBJ)
rm -rf $(PROTO_SRC) $(PROTO_HEADER)
rm -rf output/
Expand All @@ -110,6 +118,11 @@ sdk: $(LIB)
mkdir -p output/lib
cp sdk/ins_sdk.h output/include
cp libins_sdk.a output/lib

python: $(SDK_OBJ) sdk/ins_wrapper.o
$(CXX) -shared -fPIC -Wl,-soname,$(PY_LIB) -o $(PY_LIB) $(LDFLAGS_SO) $^
mkdir -p output/python
cp $(PY_LIB) sdk/ins_sdk.py output/python

install: $(LIB)
cp sdk/ins_sdk.h $(PREFIX)/include
Expand Down
225 changes: 225 additions & 0 deletions sdk/ins_sdk.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
#!/usr/bin/python

from ctypes import CDLL, byref, CFUNCTYPE, POINTER, Structure, cast, addressof
from ctypes import c_void_p, c_char_p, c_long, c_int, c_bool, py_object
import threading

SDKError = ('OK', 'ClusterDown', 'NoSuchKey', 'Timeout', 'LockFail',
'CleanBinlogFail', 'UserExists', 'PermissionDenied', 'PasswordError',
'UnknownUser')
NodeStatus = ('Leader', 'Candidate', 'Follower', 'Offline')
ClusterInfo = ('server_id', 'status', 'term', 'last_log_index', 'last_log_term',
'commit_index', 'last_applied')

class WatchParam:
def __init__(self, key, value, deleted, context):
self.key = key
self.value = value
self.deleted = deleted
self.context = context

class InsSDK:
class _ClusterNodeInfo(Structure):
_fields_ = [('server_id', c_char_p),
('status', c_int),
('term', c_long),
('last_log_index', c_long),
('last_log_term', c_long),
('commit_index', c_long),
('last_applied', c_long)]
class _WatchParam(Structure):
_fields_ = [('key', c_char_p),
('value', c_char_p),
('deleted', c_bool),
('context', c_void_p)]

WatchCallback = CFUNCTYPE(None, POINTER(_WatchParam), c_long, c_int)
SessionTimeoutCallback = CFUNCTYPE(None, c_long, c_void_p)

def __init__(self, members):
if isinstance(members, basestring):
self._sdk = _ins.GetSDK(members)
else:
self._sdk = _ins.GetSDKFromArray(members)
self._local = threading.local()
self._local.errno = c_int()

def __del__(self):
if _ins != None:
_ins.DeleteSDK(self._sdk)

def error(self):
return SDKError[self._local.errno]

def show(self):
count = c_int()
cluster_ptr = _ins.SDKShowCluster(self._sdk, byref(count))
count = count.value
ClusterArray = self._ClusterNodeInfo * count
clusters = ClusterArray.from_address(cluster_ptr)
cluster_list = []
for i in xrange(count):
cluster_list.append({
'server_id' : str(clusters[i].server_id),
'status' : NodeStatus[clusters[i].status],
'term' : clusters[i].term,
'last_log_index' : clusters[i].last_log_index,
'last_log_term' : clusters[i].last_log_term,
'commit_index' : clusters[i].commit_index,
'last_applied' : clusters[i].last_applied
})
_ins.DeleteClusterArray(cluster_ptr)
return cluster_list

def get(self, key):
return _ins.SDKGet(self._sdk, key, byref(self._local.errno))

def put(self, key, value):
return _ins.SDKPut(self._sdk, key, value, byref(self._local.errno))

def delete(self, key):
return _ins.SDKDelete(self._sdk, key, byref(self._local.errno))

def scan(self, start_key, end_key):
self._local.errno = c_int(0)
return ScanResult(_ins.SDKScan(self._sdk, start_key, end_key))

def watch(self, key, callback, context):
ctx = py_object(context)
self._contexts[addressof(ctx)] = ctx
self._callback[id(callback)] = callback
def _watch_wrapper(param, cb, error):
param = param.contents
context = cast(c_void_p(param.context), POINTER(py_object)).contents
pm = WatchParam(param.key, param.value, param.deleted, context.value)
InsSDK._callback[cb](pm, SDKError[error])
del InsSDK._callback[cb]
del InsSDK._contexts[addressof(context)]
return _ins.SDKWatch(self._sdk, key, self.WatchCallback(_watch_wrapper), \
id(callback), byref(ctx), byref(self._local.errno))

def lock(self, key):
return _ins.SDKLock(self._sdk, key, byref(self._local.errno))

def trylock(self, key):
return _ins.SDKTryLock(self._sdk, key, byref(self._local.errno))

def unlock(self, key):
return _ins.SDKUnLock(self._sdk, key, byref(self._local.errno))

def login(self, username, password):
return _ins.SDKLogin(self._sdk, username, password, byref(self._local.errno))

def logout(self):
return _ins.SDKLogout(self._sdk, byref(self._local.errno))

def register(self, username, password):
return _ins.SDKRegister(self._sdk, username, password, byref(self._local.errno))

def get_session_id(self):
return _ins.SDKGetSessionID(self._sdk)

def get_current_user_id(self):
return _ins.SDKGetCurrentUserID(self._sdk)

def is_logged_in(self):
return _ins.SDKIsLoggedIn(self._sdk)

def register_session_timeout(self, callback, context):
ctx = py_object(context)
self._contexts[addressof(context)] = context
self._callback[id(callback)] = callback
def _timeout_wrapper(cb, ctx):
context = cast(ctx, POINTER(py_object)).contents
InsSDK._callback[cb](context.value)
del InsSDK._callback[cb]
del InsSDK._contexts[addressof(context)]
_ins.SDKRegisterSessionTimeout(self._sdk, self.SessionTimeoutCallback(wrapper), \
id(callback), byref(ctx))

_contexts = {}
_callback = {}

# <-- InsSDK class definition ends here

class ScanResult:
def __init__(self, res_ptr):
self.scanner = res_ptr

def __del__(self):
if _ins != None:
_ins.DeleteScanResult(self.scanner)

def __iter__(self):
return self

def done(self):
return _ins.ScanResultDone(self.scanner)

def error(self):
return SDKError[_ins.ScanResultError(self.scanner)]

def key(self):
return _ins.ScanResultKey(self.scanner)

def value(self):
return _ins.ScanResultValue(self.scanner)

def pair(self):
return self.key(), self.value()

def next(self):
if self.done():
raise StopIteration()
else:
key, value = self.pair()
_ins.ScanResultNext(self.scanner)
return key, value

# <-- ScanResult class definition ends here

_ins = CDLL('./libins_py.so')
def _set_function_sign():
_ins.SDKShowCluster.argtypes = [c_void_p, POINTER(c_int)]
_ins.SDKShowCluster.restype = c_void_p
_ins.SDKGet.argtypes = [c_void_p, c_char_p, POINTER(c_int)]
_ins.SDKGet.restype = c_char_p
_ins.SDKPut.argtypes = [c_void_p, c_char_p, c_char_p, POINTER(c_int)]
_ins.SDKPut.restype = c_bool
_ins.SDKDelete.argtypes = [c_void_p, c_char_p, POINTER(c_int)]
_ins.SDKDelete.restype = c_bool
_ins.SDKScan.argtypes = [c_void_p, c_char_p, c_char_p]
_ins.SDKScan.restype = c_void_p
_ins.SDKWatch.argtypes = [c_void_p, c_char_p, InsSDK.WatchCallback, \
c_long, c_void_p, c_void_p]
_ins.SDKWatch.restype = c_bool
_ins.SDKLock.argtypes = [c_void_p, c_char_p, POINTER(c_int)]
_ins.SDKLock.restype = c_bool
_ins.SDKTryLock.argtypes = [c_void_p, c_char_p, POINTER(c_int)]
_ins.SDKTryLock.restype = c_bool
_ins.SDKUnLock.argtypes = [c_void_p, c_char_p, POINTER(c_int)]
_ins.SDKUnLock.restype = c_bool
_ins.SDKLogin.argtypes = [c_void_p, c_char_p, c_char_p, POINTER(c_int)]
_ins.SDKLogin.restype = c_bool
_ins.SDKLogout.argtypes = [c_void_p, POINTER(c_int)]
_ins.SDKLogout.restype = c_bool
_ins.SDKRegister.argtypes = [c_void_p, c_char_p, c_char_p, POINTER(c_int)]
_ins.SDKRegister.restype = c_bool
_ins.SDKGetSessionID.argtypes = [c_void_p]
_ins.SDKGetSessionID.restype = c_char_p
_ins.SDKGetCurrentUserID.argtypes = [c_void_p]
_ins.SDKGetCurrentUserID.restype = c_char_p
_ins.SDKIsLoggedIn.argtypes = [c_void_p]
_ins.SDKIsLoggedIn.restype = c_bool
_ins.SDKRegisterSessionTimeout.argtypes = [c_void_p, InsSDK.SessionTimeoutCallback, \
c_long, c_void_p]
_ins.ScanResultDone.argtypes = [c_void_p]
_ins.ScanResultDone.restype = c_bool
_ins.ScanResultError.argtypes = [c_void_p]
_ins.ScanResultError.restype = c_int
_ins.ScanResultKey.argtypes = [c_void_p]
_ins.ScanResultKey.restype = c_char_p
_ins.ScanResultValue.argtypes = [c_void_p]
_ins.ScanResultValue.restype = c_char_p
_set_function_sign()

Loading

0 comments on commit 3624350

Please sign in to comment.