Skip to content

Commit

Permalink
Merge pull request #1 from RyougiNevermore/master
Browse files Browse the repository at this point in the history
v0.0.1
  • Loading branch information
RyougiNevermore committed Aug 4, 2019
2 parents 320054c + 09d3df6 commit b991487
Show file tree
Hide file tree
Showing 10 changed files with 952 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

.idea
140 changes: 138 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,138 @@
# snailx
Asynchronous service framework, event-driven design, please do not block me.
## SnailX is a tool-kit for building **reactive** applications with **Golang**

> SnailX is Asynchronous
SnailX is *event driven* and *non blocking*. This means your app can handle a lot of concurrency using a small number of kernel threads. SnailX lets your app scale with minimal hardware.

> SnailX is Fun
Unlike restrictive traditional application containers, SnailX gives you incredible power and agility to create compelling, scalable, 21st century applications the way you want to, with a minimum of fuss, in the language you want.



## Install

```go
go get github.com/pharosnet/snailx
```

## Basic Usage

* snailx

```go
// using snailx
x := snailx.New()
// default service bus, event loop type
x.Deploy(&BookSnail{})
// worker type service bus
x.DeployWithOptions(&BookConsumerSnail{}, snailx.SnailOptions{ServiceBusKind:snailx.WORKER_SERVICE_BUS, WorkersNum:4})
// graceful shutdown
sigint := make(chan os.Signal,1)
signal.Notify(sigint, syscall.SIGINT, syscall.SIGTERM)
sig := <-sigint
fmt.Println("sigint:", sig)
// call snalix stop
if err := x.Stop(); err != nil {
fmt.Println("stop failed", err)
}
```



* snail app

```go
// implement snailx.Snail
type BookSnail struct {
bus snailx.ServiceBus
}

func (s *BookSnail) SetServiceBus(bus snailx.ServiceBus) {
s.bus = bus
}

func (s *BookSnail) Start() {
// deploy service to service bus
// the service address must be identity
if err := s.bus.Deploy("helloWorkService", HelloWorkService); err != nil {
fmt.Println("deploy service failed", err)
return
}
}

func (s *BookSnail) Stop() {
if err := s.bus.UnDeploy("helloWorkService"); err != nil {
fmt.Println("unDeploy service failed", err)
return
}
}
```

```go
// implement snailx.Snail
type BookConsumerSnail struct {
bus snailx.ServiceBus
}

func (s *BookConsumerSnail) SetServiceBus(bus snailx.ServiceBus) {
s.bus = bus
}

func (s *BookConsumerSnail) Start() {
// invoke service which is deployed to the service bus
// the first param is service address
// the second param must be a func which has three param (the first must be bool type, the second must be service result type, the last must be error type)
if err := s.bus.Invoke("helloWorkService", &BookGetArg{Name:"book name"}, func(ok bool, book *Book, err error) {
fmt.Println("ok:", ok)
fmt.Println("book:", book)
fmt.Println("err:", err)
}); err != nil {
fmt.Println("invoke service failed", err)
}
}

func (s *BookConsumerSnail) Stop() {}
```



* service func

```go
type BookGetArg struct {
Name string
}

type Book struct {
Id string
Name string
PublishDate time.Time
}

// service function, the type of param is must be noted.
// the first could be every prt type
// the second must be *snailx.ServiceHandler
var HelloWorkService = func(arg *BookGetArg, handler *snailx.ServiceHandler) {
bookName := arg.Name
book := &Book{
Id: "some id",
Name:bookName,
PublishDate:time.Now(),
}
// return succeeded result
handler.Succeed(book)
// return failed cause
//handler.Failed(fmt.Errorf("some cause"))
}
```



## Todo

- [ ] cluster
- [ ] snail http
- [ ] snail pg client
- [ ] snail net

5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module snailx

go 1.12

require github.com/nats-io/nuid v1.0.1 // indirect
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
225 changes: 225 additions & 0 deletions json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
package snailx

import (
"encoding/json"
"reflect"
)

var emptyJsonObjectType = reflect.TypeOf(&JsonObject{})

type JsonObject struct {
data map[string]interface{}
}

func (j *JsonObject) Encode() []byte {
if j.data == nil {
return []byte("{}")
}
if p, err := json.Marshal(j.data); err == nil {
return p
}
return []byte("{}")
}

func (j *JsonObject) Decode(p []byte) error {
j.data = make(map[string]interface{})
return json.Unmarshal(p, &j.data)
}

func (j *JsonObject) Put(key string, val interface{}) {
if j.data == nil {
j.data = make(map[string]interface{})
}
j.data[key] = val
}

func (j *JsonObject) Get(key string) interface{} {
if j.data == nil {
return nil
}
if v, has := j.data[key]; has {
return v
}
return nil
}

func (j *JsonObject) GetString(key string) string {
if j.data == nil {
return ""
}
if v, has := j.data[key]; has {
if value, ok := v.(string); ok {
return value
}
return ""
}
return ""
}

func (j *JsonObject) GetStringWithDefault(key string, def string) string {
if j.data == nil {
return def
}
if v, has := j.data[key]; has {
if value, ok := v.(string); ok && value != "" {
return value
}
return def
}
return def
}

func (j *JsonObject) GetInt(key string) int {
if j.data == nil {
return 0
}
if v, has := j.data[key]; has {
if value, ok := v.(int); ok {
return value
}
return 0
}
return 0
}

func (j *JsonObject) GetIntWithDefault(key string, def int) int {
if j.data == nil {
return def
}
if v, has := j.data[key]; has {
if value, ok := v.(int); ok && value != 0 {
return value
}
return def
}
return def
}

func (j *JsonObject) GetFloat(key string) float32 {
if j.data == nil {
return 0
}
if v, has := j.data[key]; has {
if value, ok := v.(float32); ok {
return value
}
return 0
}
return 0
}

func (j *JsonObject) GetFloatWithDefault(key string, def float32) float32 {
if j.data == nil {
return def
}
if v, has := j.data[key]; has {
if value, ok := v.(float32); ok && value != 0 {
return value
}
return def
}
return def
}

func (j *JsonObject) GetBool(key string) bool {
if j.data == nil {
return false
}
if v, has := j.data[key]; has {
if value, ok := v.(bool); ok {
return value
}
return false
}
return false
}

func (j *JsonObject) GetBoolWithDefault(key string, def bool) bool {
if j.data == nil {
return def
}
if v, has := j.data[key]; has {
if value, ok := v.(bool); ok && value == false {
return value
}
return def
}
return def
}

func (j *JsonObject) GetJsonObject(key string) *JsonObject {
if j.data == nil {
return nil
}
if v, has := j.data[key]; has {
if value, ok := v.(map[string]interface{}); ok {
return &JsonObject{data: value}
}
return nil
}
return nil
}

func (j *JsonObject) GetJsonObjectWithDefault(key string, def *JsonObject) *JsonObject {
if j.data == nil {
return def
}
if v, has := j.data[key]; has {
if value, ok := v.(map[string]interface{}); ok && value != nil {
return &JsonObject{data: value}
}
return def
}
return def
}

type JsonArray struct {
data []interface{}
}

func (j *JsonArray) Encode() []byte {
if j.data == nil {
return []byte("[]")
}
if p, err := json.Marshal(j.data); err == nil {
return p
}
return []byte("[]")
}

func (j *JsonArray) Decode(p []byte) error {
j.data = make([]interface{}, 0, 1)
return json.Unmarshal(p, &j.data)
}

func (j *JsonArray) Add(key string, v interface{}) {
if j.data == nil {
j.data = make([]interface{}, 0, 1)
}
if v == nil {
return
}
if value, ok := v.(*JsonObject); ok && value != nil && value.data != nil && len(value.data) > 0 {
j.data = append(j.data, value.data)
return
}
if value, ok := v.(JsonObject); ok && value.data != nil && len(value.data) > 0 {
j.data = append(j.data, value.data)
return
}
if reflect.TypeOf(v).Kind() == reflect.Struct || reflect.TypeOf(v).Kind() == reflect.Ptr {
p, err := json.Marshal(v)
if err != nil {
panic(err)
}
data := make(map[string]interface{})
err = json.Unmarshal(p, data)
if err != nil {
panic(err)
}
j.data = append(j.data, data)
return
}
j.data = append(j.data, v)
return
}
8 changes: 8 additions & 0 deletions log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package snailx

type Logger interface {
Infof(format string, args ...interface{})
Warningf(format string, args ...interface{})
Errorf(format string, args ...interface{})
Fatalf(format string, args ...interface{})
}
Loading

0 comments on commit b991487

Please sign in to comment.