mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 20:23:06 +00:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a2b253b40 | ||
|
|
f65ecdf767 | ||
|
|
ee3f9c6ecd | ||
|
|
52134f9e57 | ||
|
|
21cd5c9882 | ||
|
|
23587d0b0f | ||
|
|
ce6fa906d3 | ||
|
|
0e20fe5b4e | ||
|
|
978d6af359 | ||
|
|
812088b5ab | ||
|
|
bf54a66346 | ||
|
|
5fb4580108 | ||
|
|
f1c9f9b9dc | ||
|
|
f15cd1d458 | ||
|
|
24a2df9383 | ||
|
|
176e4df90c | ||
|
|
babd730d07 | ||
|
|
fe9640e2dd | ||
|
|
906008f667 | ||
|
|
2da2f121c8 | ||
|
|
a0d2c7172c | ||
|
|
463a789898 | ||
|
|
175529b114 | ||
|
|
6f6039c136 | ||
|
|
2b13eb250d | ||
|
|
84cb4bb4c1 |
15
HISTORY.md
15
HISTORY.md
@@ -1,4 +1,17 @@
|
|||||||
v0.9.0 (2014-11-17)
|
v0.9.3 (2014-1-5)
|
||||||
|
-----------
|
||||||
|
* Add : mongo createIndex
|
||||||
|
* Update : sproto
|
||||||
|
* bugfix : sharedata check dirty flag when len/pairs metamethod
|
||||||
|
* bugfix : multicast
|
||||||
|
|
||||||
|
v0.9.2 (2014-12-8)
|
||||||
|
-----------
|
||||||
|
* Simplify the message queue
|
||||||
|
* Add create_index in mongo driver
|
||||||
|
* Fix a bug in big-endian architecture (sproto)
|
||||||
|
|
||||||
|
v0.9.0 / v0.9.1 (2014-11-17)
|
||||||
-----------
|
-----------
|
||||||
* Add UDP support
|
* Add UDP support
|
||||||
* Add IPv6 support
|
* Add IPv6 support
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ mc_unpacklocal(lua_State *L) {
|
|||||||
if (sz != sizeof(*pack)) {
|
if (sz != sizeof(*pack)) {
|
||||||
return luaL_error(L, "Invalid multicast package size %d", sz);
|
return luaL_error(L, "Invalid multicast package size %d", sz);
|
||||||
}
|
}
|
||||||
lua_settop(L, 1);
|
lua_pushlightuserdata(L, *pack);
|
||||||
lua_pushlightuserdata(L, (*pack)->data);
|
lua_pushlightuserdata(L, (*pack)->data);
|
||||||
lua_pushunsigned(L, (*pack)->size);
|
lua_pushunsigned(L, (*pack)->size);
|
||||||
return 3;
|
return 3;
|
||||||
@@ -92,6 +92,8 @@ mc_unpacklocal(lua_State *L) {
|
|||||||
/*
|
/*
|
||||||
lightuserdata struct mc_package **
|
lightuserdata struct mc_package **
|
||||||
integer reference
|
integer reference
|
||||||
|
|
||||||
|
return mc_package *
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
mc_bindrefer(lua_State *L) {
|
mc_bindrefer(lua_State *L) {
|
||||||
@@ -102,16 +104,17 @@ mc_bindrefer(lua_State *L) {
|
|||||||
}
|
}
|
||||||
(*pack)->reference = ref;
|
(*pack)->reference = ref;
|
||||||
|
|
||||||
return 0;
|
lua_pushlightuserdata(L, *pack);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
lightuserdata struct mc_package **
|
lightuserdata struct mc_package *
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
mc_closelocal(lua_State *L) {
|
mc_closelocal(lua_State *L) {
|
||||||
struct mc_package **ptr = lua_touserdata(L,1);
|
struct mc_package *pack = lua_touserdata(L,1);
|
||||||
struct mc_package *pack = *ptr;
|
|
||||||
|
|
||||||
int ref = __sync_sub_and_fetch(&pack->reference, 1);
|
int ref = __sync_sub_and_fetch(&pack->reference, 1);
|
||||||
if (ref <= 0) {
|
if (ref <= 0) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include "skynet_socket.h"
|
#include "skynet_socket.h"
|
||||||
|
|||||||
@@ -252,12 +252,12 @@ decode(void *ud, const char *tagname, int type, int index, struct sproto_type *s
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case SPROTO_TINTEGER: {
|
case SPROTO_TINTEGER: {
|
||||||
// notice: in lua 5.2, 52bit integer support (not 64)
|
// notice: in lua 5.2, 52bit integer support (not 64)
|
||||||
lua_Integer v = *(lua_Integer *)value;
|
lua_Integer v = *(uint64_t*)value;
|
||||||
lua_pushinteger(L, v);
|
lua_pushinteger(L, v);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPROTO_TBOOLEAN: {
|
case SPROTO_TBOOLEAN: {
|
||||||
int v = *(lua_Integer*)value;
|
int v = *(uint64_t*)value;
|
||||||
lua_pushboolean(L,v);
|
lua_pushboolean(L,v);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -971,7 +971,7 @@ decode_array(sproto_callback cb, void *ud, struct field *f, uint8_t * stream) {
|
|||||||
}
|
}
|
||||||
case SPROTO_TBOOLEAN:
|
case SPROTO_TBOOLEAN:
|
||||||
for (i=0;i<sz;i++) {
|
for (i=0;i<sz;i++) {
|
||||||
int value = stream[i];
|
uint64_t value = stream[i];
|
||||||
cb(ud, f->name, SPROTO_TBOOLEAN, i+1, NULL, &value, sizeof(value));
|
cb(ud, f->name, SPROTO_TBOOLEAN, i+1, NULL, &value, sizeof(value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -120,6 +120,8 @@ function mongo.client( conf )
|
|||||||
local obj = {
|
local obj = {
|
||||||
host = first.host,
|
host = first.host,
|
||||||
port = first.port or 27017,
|
port = first.port or 27017,
|
||||||
|
username = first.username,
|
||||||
|
password = first.password,
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.__id = 0
|
obj.__id = 0
|
||||||
@@ -227,6 +229,10 @@ function mongo_collection:insert(doc)
|
|||||||
sock:request(pack)
|
sock:request(pack)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function mongo_collection:safe_insert(doc)
|
||||||
|
return self.database:runCommand("insert", self.name, "documents", {bson_encode(doc)})
|
||||||
|
end
|
||||||
|
|
||||||
function mongo_collection:batch_insert(docs)
|
function mongo_collection:batch_insert(docs)
|
||||||
for i=1,#docs do
|
for i=1,#docs do
|
||||||
if docs[i]._id == nil then
|
if docs[i]._id == nil then
|
||||||
@@ -276,6 +282,62 @@ function mongo_collection:find(query, selector)
|
|||||||
} , cursor_meta)
|
} , cursor_meta)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- collection:createIndex({username = 1}, {unique = true})
|
||||||
|
function mongo_collection:createIndex(keys, option)
|
||||||
|
local name = option.name
|
||||||
|
option.name = nil
|
||||||
|
|
||||||
|
if not name then
|
||||||
|
for k, v in pairs(keys) do
|
||||||
|
name = (name == nil) and k or (name .. "_" .. k)
|
||||||
|
name = name .. "_" .. v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local doc = {};
|
||||||
|
doc.name = name
|
||||||
|
doc.key = keys
|
||||||
|
for k, v in pairs(option) do
|
||||||
|
doc[k] = v
|
||||||
|
end
|
||||||
|
return self.database:runCommand("createIndexes", self.name, "indexes", {doc})
|
||||||
|
end
|
||||||
|
|
||||||
|
mongo_collection.ensureIndex = mongo_collection.createIndex;
|
||||||
|
|
||||||
|
|
||||||
|
function mongo_collection:drop()
|
||||||
|
return self.database:runCommand("drop", self.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- collection:dropIndex("age_1")
|
||||||
|
-- collection:dropIndex("*")
|
||||||
|
function mongo_collection:dropIndex(indexName)
|
||||||
|
return self.database:runCommand("dropIndexes", self.name, "index", indexName)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- collection:findAndModify({query = {name = "userid"}, update = {["$inc"] = {nextid = 1}}, })
|
||||||
|
-- keys, value type
|
||||||
|
-- query, table
|
||||||
|
-- sort, table
|
||||||
|
-- remove, bool
|
||||||
|
-- update, table
|
||||||
|
-- new, bool
|
||||||
|
-- fields, bool
|
||||||
|
-- upsert, boolean
|
||||||
|
function mongo_collection:findAndModify(doc)
|
||||||
|
assert(doc.query)
|
||||||
|
assert(doc.update or doc.remove)
|
||||||
|
|
||||||
|
local cmd = {"findAndModify", self.name};
|
||||||
|
for k, v in pairs(doc) do
|
||||||
|
table.insert(cmd, k)
|
||||||
|
table.insert(cmd, v)
|
||||||
|
end
|
||||||
|
return self.database:runCommand(unpack(cmd))
|
||||||
|
end
|
||||||
|
|
||||||
function mongo_cursor:hasNext()
|
function mongo_cursor:hasNext()
|
||||||
if self.__ptr == nil then
|
if self.__ptr == nil then
|
||||||
if self.__document == nil then
|
if self.__document == nil then
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ local function genkey(self)
|
|||||||
return key
|
return key
|
||||||
end
|
end
|
||||||
|
|
||||||
function meta:__index(key)
|
local function getcobj(self)
|
||||||
local obj = self.__obj
|
local obj = self.__obj
|
||||||
if isdirty(obj) then
|
if isdirty(obj) then
|
||||||
local newobj, newtbl = needupdate(self.__gcobj)
|
local newobj, newtbl = needupdate(self.__gcobj)
|
||||||
@@ -67,6 +67,11 @@ function meta:__index(key)
|
|||||||
obj = self.__obj
|
obj = self.__obj
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
return obj
|
||||||
|
end
|
||||||
|
|
||||||
|
function meta:__index(key)
|
||||||
|
local obj = getcobj(self)
|
||||||
local v = index(obj, key)
|
local v = index(obj, key)
|
||||||
if type(v) == "userdata" then
|
if type(v) == "userdata" then
|
||||||
local r = setmetatable({
|
local r = setmetatable({
|
||||||
@@ -83,11 +88,11 @@ function meta:__index(key)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function meta:__len()
|
function meta:__len()
|
||||||
return len(self.__obj)
|
return len(getcobj(self))
|
||||||
end
|
end
|
||||||
|
|
||||||
local function conf_ipairs(self, index)
|
local function conf_ipairs(self, index)
|
||||||
local obj = self.__obj
|
local obj = getcobj(self)
|
||||||
index = index + 1
|
index = index + 1
|
||||||
local value = rawget(self, index)
|
local value = rawget(self, index)
|
||||||
if value then
|
if value then
|
||||||
@@ -109,7 +114,8 @@ function meta:__pairs()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function conf.next(obj, key)
|
function conf.next(obj, key)
|
||||||
local nextkey = core.nextkey(obj.__obj, key)
|
local cobj = getcobj(obj)
|
||||||
|
local nextkey = core.nextkey(cobj, key)
|
||||||
if nextkey then
|
if nextkey then
|
||||||
return nextkey, obj[nextkey]
|
return nextkey, obj[nextkey]
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ socket_message[1] = function(id, size, data)
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
if s.buffer_limit and sz > s.buffer_limit then
|
if s.buffer_limit and sz > s.buffer_limit then
|
||||||
skynet.error(string.format("socket buffer overlow: fd=%d size=%d", id , sz))
|
skynet.error(string.format("socket buffer overflow: fd=%d size=%d", id , sz))
|
||||||
driver.clear(s.buffer,buffer_pool)
|
driver.clear(s.buffer,buffer_pool)
|
||||||
driver.close(id)
|
driver.close(id)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -313,9 +313,12 @@ local function packgroup(t,p)
|
|||||||
local tt, tp
|
local tt, tp
|
||||||
local alltypes = {}
|
local alltypes = {}
|
||||||
for name in pairs(t) do
|
for name in pairs(t) do
|
||||||
alltypes[name] = #alltypes
|
|
||||||
table.insert(alltypes, name)
|
table.insert(alltypes, name)
|
||||||
end
|
end
|
||||||
|
table.sort(alltypes) -- make result stable
|
||||||
|
for idx, name in ipairs(alltypes) do
|
||||||
|
alltypes[name] = idx - 1
|
||||||
|
end
|
||||||
tt = {}
|
tt = {}
|
||||||
for _,name in ipairs(alltypes) do
|
for _,name in ipairs(alltypes) do
|
||||||
table.insert(tt, packtype(name, t[name], alltypes))
|
table.insert(tt, packtype(name, t[name], alltypes))
|
||||||
|
|||||||
@@ -68,18 +68,20 @@ end
|
|||||||
local function publish(c , source, pack, size)
|
local function publish(c , source, pack, size)
|
||||||
local group = channel[c]
|
local group = channel[c]
|
||||||
if group == nil then
|
if group == nil then
|
||||||
-- dead channel, delete the pack
|
-- dead channel, delete the pack. mc.bind returns the pointer in pack
|
||||||
mc.bind(pack, 1)
|
local pack = mc.bind(pack, 1)
|
||||||
mc.close(pack)
|
mc.close(pack)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
mc.bind(pack, channel_n[c])
|
mc.bind(pack, channel_n[c])
|
||||||
local msg = skynet.tostring(pack, size)
|
local msg = skynet.tostring(pack, size)
|
||||||
for k in pairs(group) do
|
for k in pairs(group) do
|
||||||
|
-- the msg is a pointer to the real message, publish pointer in local is ok.
|
||||||
skynet.redirect(k, source, "multicast", c , msg)
|
skynet.redirect(k, source, "multicast", c , msg)
|
||||||
end
|
end
|
||||||
local remote = channel_remote[c]
|
local remote = channel_remote[c]
|
||||||
if remote then
|
if remote then
|
||||||
|
-- remote publish should unpack the pack, because we should not publish the pointer out.
|
||||||
local _, msg, sz = mc.unpack(pack, size)
|
local _, msg, sz = mc.unpack(pack, size)
|
||||||
local msg = skynet.tostring(msg,sz)
|
local msg = skynet.tostring(msg,sz)
|
||||||
for node in pairs(remote) do
|
for node in pairs(remote) do
|
||||||
|
|||||||
@@ -32,12 +32,9 @@ struct message_queue {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct global_queue {
|
struct global_queue {
|
||||||
uint32_t head;
|
struct message_queue *head;
|
||||||
uint32_t tail;
|
struct message_queue *tail;
|
||||||
struct message_queue ** queue;
|
int lock;
|
||||||
// We use a separated flag array to ensure the mq is pushed.
|
|
||||||
// See the comments below.
|
|
||||||
struct message_queue *list;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct global_queue *Q = NULL;
|
static struct global_queue *Q = NULL;
|
||||||
@@ -45,63 +42,36 @@ static struct global_queue *Q = NULL;
|
|||||||
#define LOCK(q) while (__sync_lock_test_and_set(&(q)->lock,1)) {}
|
#define LOCK(q) while (__sync_lock_test_and_set(&(q)->lock,1)) {}
|
||||||
#define UNLOCK(q) __sync_lock_release(&(q)->lock);
|
#define UNLOCK(q) __sync_lock_release(&(q)->lock);
|
||||||
|
|
||||||
#define GP(p) ((p) % MAX_GLOBAL_MQ)
|
|
||||||
|
|
||||||
void
|
void
|
||||||
skynet_globalmq_push(struct message_queue * queue) {
|
skynet_globalmq_push(struct message_queue * queue) {
|
||||||
struct global_queue *q= Q;
|
struct global_queue *q= Q;
|
||||||
|
|
||||||
uint32_t tail = GP(__sync_fetch_and_add(&q->tail,1));
|
LOCK(q)
|
||||||
|
assert(queue->next == NULL);
|
||||||
// only one thread can set the slot (change q->queue[tail] from NULL to queue)
|
if(q->tail) {
|
||||||
if (!__sync_bool_compare_and_swap(&q->queue[tail], NULL, queue)) {
|
q->tail->next = queue;
|
||||||
// The queue may full seldom, save queue in list
|
q->tail = queue;
|
||||||
assert(queue->next == NULL);
|
} else {
|
||||||
struct message_queue * last;
|
q->head = q->tail = queue;
|
||||||
do {
|
|
||||||
last = q->list;
|
|
||||||
queue->next = last;
|
|
||||||
} while(!__sync_bool_compare_and_swap(&q->list, last, queue));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
UNLOCK(q)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct message_queue *
|
struct message_queue *
|
||||||
skynet_globalmq_pop() {
|
skynet_globalmq_pop() {
|
||||||
struct global_queue *q = Q;
|
struct global_queue *q = Q;
|
||||||
uint32_t head = q->head;
|
|
||||||
|
|
||||||
if (head == q->tail) {
|
LOCK(q)
|
||||||
// The queue is empty.
|
struct message_queue *mq = q->head;
|
||||||
return NULL;
|
if(mq) {
|
||||||
}
|
q->head = mq->next;
|
||||||
|
if(q->head == NULL) {
|
||||||
uint32_t head_ptr = GP(head);
|
assert(mq == q->tail);
|
||||||
|
q->tail = NULL;
|
||||||
struct message_queue * list = q->list;
|
|
||||||
if (list) {
|
|
||||||
// If q->list is not empty, try to load it back to the queue
|
|
||||||
struct message_queue *newhead = list->next;
|
|
||||||
if (__sync_bool_compare_and_swap(&q->list, list, newhead)) {
|
|
||||||
// try load list only once, if success , push it back to the queue.
|
|
||||||
list->next = NULL;
|
|
||||||
skynet_globalmq_push(list);
|
|
||||||
}
|
}
|
||||||
|
mq->next = NULL;
|
||||||
}
|
}
|
||||||
|
UNLOCK(q)
|
||||||
struct message_queue * mq = q->queue[head_ptr];
|
|
||||||
if (mq == NULL) {
|
|
||||||
// globalmq push not complete
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (!__sync_bool_compare_and_swap(&q->head, head, head+1)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
// only one thread can get the slot (change q->queue[head_ptr] to NULL)
|
|
||||||
if (!__sync_bool_compare_and_swap(&q->queue[head_ptr], mq, NULL)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mq;
|
return mq;
|
||||||
}
|
}
|
||||||
@@ -243,8 +213,6 @@ void
|
|||||||
skynet_mq_init() {
|
skynet_mq_init() {
|
||||||
struct global_queue *q = skynet_malloc(sizeof(*q));
|
struct global_queue *q = skynet_malloc(sizeof(*q));
|
||||||
memset(q,0,sizeof(*q));
|
memset(q,0,sizeof(*q));
|
||||||
q->queue = skynet_malloc(MAX_GLOBAL_MQ * sizeof(struct message_queue *));
|
|
||||||
memset(q->queue, 0, sizeof(struct message_queue *) * MAX_GLOBAL_MQ);
|
|
||||||
Q=q;
|
Q=q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -628,7 +628,7 @@ append_sendbuffer_(struct socket_server *ss, struct wb_list *s, struct request_s
|
|||||||
struct write_buffer * buf = MALLOC(size);
|
struct write_buffer * buf = MALLOC(size);
|
||||||
struct send_object so;
|
struct send_object so;
|
||||||
buf->userobject = send_object_init(ss, &so, request->buffer, request->sz);
|
buf->userobject = send_object_init(ss, &so, request->buffer, request->sz);
|
||||||
buf->ptr = so.buffer+n;
|
buf->ptr = (char*)so.buffer+n;
|
||||||
buf->sz = so.sz - n;
|
buf->sz = so.sz - n;
|
||||||
buf->buffer = request->buffer;
|
buf->buffer = request->buffer;
|
||||||
buf->next = NULL;
|
buf->next = NULL;
|
||||||
|
|||||||
10
test/testdeadloop.lua
Normal file
10
test/testdeadloop.lua
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
local skynet = require "skynet"
|
||||||
|
local function dead_loop()
|
||||||
|
while true do
|
||||||
|
skynet.sleep(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
skynet.start(function()
|
||||||
|
skynet.fork(dead_loop)
|
||||||
|
end)
|
||||||
90
test/testmongodb.lua
Normal file
90
test/testmongodb.lua
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
local skynet = require "skynet"
|
||||||
|
local mongo = require "mongo"
|
||||||
|
local bson = require "bson"
|
||||||
|
|
||||||
|
local host, db_name = ...
|
||||||
|
|
||||||
|
function test_insert_without_index()
|
||||||
|
local db = mongo.client({host = host})
|
||||||
|
|
||||||
|
db[db_name].testdb:dropIndex("*")
|
||||||
|
db[db_name].testdb:drop()
|
||||||
|
|
||||||
|
local ret = db[db_name].testdb:safe_insert({test_key = 1});
|
||||||
|
assert(ret and ret.n == 1)
|
||||||
|
|
||||||
|
local ret = db[db_name].testdb:safe_insert({test_key = 1});
|
||||||
|
assert(ret and ret.n == 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function test_insert_with_index()
|
||||||
|
local db = mongo.client({host = host})
|
||||||
|
|
||||||
|
db[db_name].testdb:dropIndex("*")
|
||||||
|
db[db_name].testdb:drop()
|
||||||
|
|
||||||
|
db[db_name].testdb:ensureIndex({test_key = 1}, {unique = true, name = "test_key_index"})
|
||||||
|
|
||||||
|
local ret = db[db_name].testdb:safe_insert({test_key = 1})
|
||||||
|
assert(ret and ret.n == 1)
|
||||||
|
|
||||||
|
local ret = db[db_name].testdb:safe_insert({test_key = 1})
|
||||||
|
assert(ret and ret.n == 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
function test_find_and_remove()
|
||||||
|
local db = mongo.client({host = host})
|
||||||
|
|
||||||
|
db[db_name].testdb:dropIndex("*")
|
||||||
|
db[db_name].testdb:drop()
|
||||||
|
|
||||||
|
db[db_name].testdb:ensureIndex({test_key = 1}, {unique = true, name = "test_key_index"})
|
||||||
|
|
||||||
|
local ret = db[db_name].testdb:safe_insert({test_key = 1})
|
||||||
|
assert(ret and ret.n == 1)
|
||||||
|
|
||||||
|
local ret = db[db_name].testdb:findOne({test_key = 1})
|
||||||
|
assert(ret and ret.test_key == 1)
|
||||||
|
|
||||||
|
db[db_name].testdb:delete({test_key = 1})
|
||||||
|
|
||||||
|
local ret = db[db_name].testdb:findOne({test_key = 1})
|
||||||
|
assert(ret == nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function test_expire_index()
|
||||||
|
local db = mongo.client({host = host})
|
||||||
|
|
||||||
|
db[db_name].testdb:dropIndex("*")
|
||||||
|
db[db_name].testdb:drop()
|
||||||
|
|
||||||
|
db[db_name].testdb:ensureIndex({test_key = 1}, {unique = true, name = "test_key_index", expireAfterSeconds = 1, })
|
||||||
|
db[db_name].testdb:ensureIndex({test_date = 1}, {expireAfterSeconds = 1, })
|
||||||
|
|
||||||
|
local ret = db[db_name].testdb:safe_insert({test_key = 1, test_date = bson.date(os.time())})
|
||||||
|
assert(ret and ret.n == 1)
|
||||||
|
|
||||||
|
local ret = db[db_name].testdb:findOne({test_key = 1})
|
||||||
|
assert(ret and ret.test_key == 1)
|
||||||
|
|
||||||
|
for i = 1, 1000 do
|
||||||
|
skynet.sleep(11);
|
||||||
|
|
||||||
|
local ret = db[db_name].testdb:findOne({test_key = 1})
|
||||||
|
if ret == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(false, "test expire index failed");
|
||||||
|
end
|
||||||
|
|
||||||
|
skynet.start(function()
|
||||||
|
test_insert_without_index()
|
||||||
|
test_insert_with_index()
|
||||||
|
test_find_and_remove()
|
||||||
|
test_expire_index()
|
||||||
|
|
||||||
|
print("mongodb test finish.");
|
||||||
|
end)
|
||||||
@@ -83,6 +83,8 @@ skynet.start(function()
|
|||||||
end
|
end
|
||||||
print("testmysql success to connect to mysql server")
|
print("testmysql success to connect to mysql server")
|
||||||
|
|
||||||
|
db:query("set names utf8")
|
||||||
|
|
||||||
local res = db:query("drop table if exists cats")
|
local res = db:query("drop table if exists cats")
|
||||||
res = db:query("create table cats "
|
res = db:query("create table cats "
|
||||||
.."(id serial primary key, ".. "name varchar(5))")
|
.."(id serial primary key, ".. "name varchar(5))")
|
||||||
|
|||||||
Reference in New Issue
Block a user