Skip to content

Commit

Permalink
Merge pull request #19 from gogf/master
Browse files Browse the repository at this point in the history
日常更新
  • Loading branch information
jroam committed Jun 10, 2019
2 parents 74e5d03 + aa73c5e commit ebcc81c
Show file tree
Hide file tree
Showing 64 changed files with 1,185 additions and 405 deletions.
1 change: 1 addition & 0 deletions DONATOR.MD
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
|[wxkj](https://gitee.com/wxkj)|wechat|¥10.00
|[zhuhuan12](https://gitee.com/zhuhuan12)|gitee|¥50.00
|[zfan_codes](https://gitee.com/zfan_codes)|gitee|¥10.00
|[arden](https://github.com/arden)|alipay|¥10.00
|潘兄|wechat|¥100.00
|土豆相公|alipay|¥66.60
|上海金保证网络科技|bank|¥2000.00
Expand Down
60 changes: 60 additions & 0 deletions RELEASE.MD
Original file line number Diff line number Diff line change
@@ -1,3 +1,63 @@
# `v1.7.0`
## 新功能/改进
1. 重构改进`glog`模块:
- 去掉日志模块所有的锁机制,改为无锁设计,执行性能更加高效
- 增加日志内容的异步输出特性:https://goframe.org/os/glog/async
- 增加日志输出内容的`Json`格式支持:https://goframe.org/os/glog/json
- 增加`Flags`额外特性支持,包括文件行号打印、自定义时间格式、异步输出等特性控制:https://goframe.org/os/glog/flags
- 增加`Writer`接口支持,便于开发者进行自定义的日志功能扩展,或者与第三方服务/模块对接集成:https://goframe.org/os/glog/writer
- 修改`SetStdPrint`方法名为`SetStdoutPrint`
- 修改链式方法`StdPrint`方法名为`Stdout`
- 标记淘汰`*fln`日志输出方法,`*f`方法支持自动的换行输出
- 新增更多的链式方法支持:https://goframe.org/os/glog/chain
1. 重构改进`gmap`模块:
- 增加更多数据格式支持:`HashMap`/`ListMap`/`TreeMap`
- 简化类型名称,如`gmap.StringInterfaceMap`简化为`gmap.StrAnyMap`
- 改进`Map/Keys/Values`方法以提高性能
- 修改`BatchSet`/`BatchRemove`方法名为`Sets`/`Removes`
- 新增更多功能方法支持:https://goframe.org/container/gmap/index
1. 改进`gtime`时间模块:
- 增加并完善更多的类`PHP`时间格式支持
- 新增更多功能方法,如`FormatTo`/`LayoutTo`等等
- 详见开发文档:https://goframe.org/os/gtime/index
1. 改进`gdb`数据库模块:
- 增加对继承结构体的数据转换支持:https://goframe.org/database/gdb/senior
- 新增`GetLastSql`方法,用以在调试模式下获取最近一条执行的SQL语句
- 其他的细节处理改进
1. 改进`gtcp`通信模块:
- 完善处理细节,提高通信性能;
- 增加`TLS`服务端/客户端通信支持:https://goframe.org/net/gtcp/tls
- 增加简单协议支持,便于开发者封包/解包,并解决粘包/半包问题:https://goframe.org/net/gtcp/conn/pkg
- TCP服务端增加`Close`方法
- 更多细节查看开发文档:https://goframe.org/net/gtcp/index
1. 改进`gconv`类型转换模块
- 修改`gconv.TimeDuration`转换方法名称为`gconv.Duration`
- 新增`gconv.StructDeep``gconv.MapDeep`方法,支持递归转换
- 详见开发文档:https://goframe.org/util/gconv/struct
1. 改进`ghttp`模块:
- 日志输出增加`http/https`字段:https://goframe.org/net/ghttp/logs
- 新增`ghttp.Server.SetKeepAlive`设置方法,用以开启/关闭`KeepAlive`特性
- 增加`ghttp.Request.GetUrl`方法,用以获取当前完整的URL请求地址
- `ghttp.Client`客户端支持开发者自定义`Transport`属性,`ghttp.Client.Post`方法支持`浏览器模式`https://goframe.org/net/ghttp/client
1. 新增`gtree`树形数据结构容器支持:https://goframe.org/container/gtree/index
1. 改进`gudp`通信模块,具体请参考开发文档:https://goframe.org/net/gudp/index
1. 改进`gcfg`配置管理模块,所有`Get*`方法增加默认值支持:https://goframe.org/os/gcfg/index
1. `gredis`模块新增`DoVar`/`ReceiveVar`方法以便于开发者对执行结果进行灵活的数据格式转换:https://goframe.org/database/gredis/index
1. `gcache`模块`BatchSet`/`BatchRemove`方法名修改为`Sets`/`Removes`
1. 改进`gjson`/`gparser`模块,增加更多方法:https://goframe.org/encoding/gjson/index
1. 改进`gfile.MainPkgPath`方法,以支持不同平台的开发环境;
1. 改进`grpool`协程池模块,提高执行性能:https://goframe.org/os/grpool/index
1. 改进`TryCatch`方法,当开发者不传递`Catch`参数时,默认抑制并忽略错误的处理
1. 改进`gmlock`模块,增加`TryLockFunc`/`TryRLockFunc`方法,并且为`gmlock.Mutex`高级互斥锁对象增加`TryLockFunc`/`TryRLockFunc`方法
1. 去除`gvar.VarRead`接口类型支持

## Bug Fix
1. 解决`gdb`模块与其他第三方`ORM`模块同时使用的冲突;
1. 修复`gcron.AddOnce`方法的细节逻辑问题;
1. 修复内部`empty`模块的`IsEmpty`方法对结构体属性的空校验错误;
1. 修复`gview`模板引擎的并发安全问题;
1. 修复`ghttp.Server`的SESSION初始化过期时间问题;

# `v1.6.0` (2019-04-09)

## 新功能/改进
Expand Down
2 changes: 1 addition & 1 deletion TODO.MD
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
1. gtimer增加DelayAdd*方法返回Entry对象,以便DelayAdd*的定时任务也能进行状态控制;gcron同理需要改进;
1. 改进gdb对pgsql/mssql/oracle的支持,使用方法覆盖的方式改进操作,而不是完全依靠正则替换的方式;
1. gdb的Cache缓存功能增加可自定义缓存接口,以便支持外部缓存功能,缓存接口可以通过io.ReadWriter接口实现;

1. grpool增加支持阻塞添加任务接口;



Expand Down
8 changes: 5 additions & 3 deletions g/container/gchan/gchan.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.

// Package gchan provides graceful channel for safe operations.
// Package gchan provides graceful channel for no panic operations.
//
// It's safe to call Chan.Push/Close functions repeatedly.
package gchan
Expand All @@ -14,12 +14,13 @@ import (
"github.com/gogf/gf/g/container/gtype"
)

// Graceful channel.
type Chan struct {
channel chan interface{}
closed *gtype.Bool
}

// New creates a graceful channel with given limit.
// New creates a graceful channel with given <limit>.
func New(limit int) *Chan {
return &Chan {
channel : make(chan interface{}, limit),
Expand All @@ -31,14 +32,15 @@ func New(limit int) *Chan {
// It is safe to be called repeatedly.
func (c *Chan) Push(value interface{}) error {
if c.closed.Val() {
return errors.New("closed")
return errors.New("channel is closed")
}
c.channel <- value
return nil
}

// Pop pops value from channel.
// If there's no value in channel, it would block to wait.
// If the channel is closed, it will return a nil value immediately.
func (c *Chan) Pop() interface{} {
return <- c.channel
}
Expand Down
6 changes: 3 additions & 3 deletions g/container/gqueue/gqueue.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ const (
)

// New returns an empty queue object.
// Optional parameter <limit> is used to limit the size of the queue, which is unlimited by default.
// When <limit> is given, the queue will be static and high performance which is comparable with stdlib chan.
// Optional parameter <limit> is used to limit the size of the queue, which is unlimited in default.
// When <limit> is given, the queue will be static and high performance which is comparable with stdlib channel.
func New(limit...int) *Queue {
q := &Queue {
closed : make(chan struct{}, 0),
Expand Down Expand Up @@ -103,7 +103,7 @@ func (q *Queue) Pop() interface{} {

// Close closes the queue.
// Notice: It would notify all goroutines return immediately,
// which are being blocked reading by Pop method.
// which are being blocked reading using Pop method.
func (q *Queue) Close() {
close(q.C)
close(q.events)
Expand Down
10 changes: 5 additions & 5 deletions g/crypto/gaes/gaes.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@ func Encrypt(plainText []byte, key []byte, iv...[]byte) ([]byte, error) {
return nil, err
}
blockSize := block.BlockSize()
plainText = PKCS5Padding(plainText, blockSize)
ivValue := ([]byte)(nil)
plainText = PKCS5Padding(plainText, blockSize)
ivValue := ([]byte)(nil)
if len(iv) > 0 {
ivValue = iv[0]
} else {
ivValue = []byte(ivDefValue)
}
blockMode := cipher.NewCBCEncrypter(block, ivValue)
ciphertext := make([]byte, len(plainText))
blockMode.CryptBlocks(ciphertext, plainText)
cipherText := make([]byte, len(plainText))
blockMode.CryptBlocks(cipherText, plainText)

return ciphertext, nil
return cipherText, nil
}

// AES解密, 使用CBC模式,注意key必须为16/24/32位长度,iv初始化向量为非必需参数
Expand Down
5 changes: 4 additions & 1 deletion g/encoding/gjson/gjson_api_new_load.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,10 @@ func LoadContent(data interface{}, unsafe...bool) (*Json, error) {
var err error
var result interface{}
b := gconv.Bytes(data)
t := "json"
t := ""
if len(b) == 0 {
return New(nil, unsafe...), nil
}
// auto check data type
if json.Valid(b) {
t = "json"
Expand Down
6 changes: 3 additions & 3 deletions g/frame/gins/gins.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,13 +219,13 @@ func Redis(name...string) *gredis.Redis {
Pass : array[4],
})
} else {
glog.Errorfln(`invalid redis node configuration: "%s"`, line)
glog.Errorf(`invalid redis node configuration: "%s"`, line)
}
} else {
glog.Errorfln(`configuration for redis not found for group "%s"`, group)
glog.Errorf(`configuration for redis not found for group "%s"`, group)
}
} else {
glog.Errorfln(`incomplete configuration for redis: "redis" node not found in config file "%s"`, config.FilePath())
glog.Errorf(`incomplete configuration for redis: "redis" node not found in config file "%s"`, config.FilePath())
}
return nil
})
Expand Down
25 changes: 15 additions & 10 deletions g/internal/empty/empty.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
package empty

import (
"reflect"
"reflect"
)

// 判断给定的变量是否为空。
Expand Down Expand Up @@ -35,17 +35,22 @@ func IsEmpty(value interface{}) bool {
case string: return value == ""
case []byte: return len(value) == 0
default:
// 最后通过反射来判断
// Finally using reflect.
rv := reflect.ValueOf(value)
if rv.IsNil() {
return true
}
kind := rv.Kind()
switch kind {
case reflect.Map: fallthrough
case reflect.Slice: fallthrough
case reflect.Array:
switch rv.Kind() {
case reflect.Chan,
reflect.Map,
reflect.Slice,
reflect.Array:
return rv.Len() == 0

case reflect.Func,
reflect.Ptr,
reflect.Interface,
reflect.UnsafePointer:
if rv.IsNil() {
return true
}
}
}
return false
Expand Down
4 changes: 3 additions & 1 deletion g/net/ghttp/ghttp_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ func (r *Response) WriteStatus(status int, content...string) {
// 状态码注册回调函数处理
if status != http.StatusOK {
if f := r.request.Server.getStatusHandler(status, r.request); f != nil {
f(r.request)
r.Server.niceCallFunc(func() {
f(r.request)
})
// 防止多次设置(http: multiple response.WriteHeader calls)
if r.Status == 0 {
r.WriteHeader(status)
Expand Down
5 changes: 4 additions & 1 deletion g/net/ghttp/ghttp_response_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ func (r *Response) buildInVars(params...map[string]interface{}) map[string]inter
} else {
vars = make(map[string]interface{})
}
vars["Config"] = gins.Config().GetMap("")
// 当配置文件不存在时就不赋值该模板变量,不然会报错
if c := gins.Config(); c.FilePath() != "" {
vars["Config"] = c.GetMap("")
}
vars["Cookie"] = r.request.Cookie.Map()
vars["Session"] = r.request.Session.Map()
vars["Get"] = r.request.GetQueryMap()
Expand Down
4 changes: 2 additions & 2 deletions g/net/ghttp/ghttp_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ func (s *Server) Run() error {
// 阻塞等待服务执行完成
<- s.closeChan

glog.Printfln("%d: all servers shutdown", gproc.Pid())
glog.Printf("%d: all servers shutdown", gproc.Pid())
return nil
}

Expand All @@ -400,7 +400,7 @@ func Wait() {
// 阻塞等待服务执行完成
<- allDoneChan

glog.Printfln("%d: all servers shutdown", gproc.Pid())
glog.Printf("%d: all servers shutdown", gproc.Pid())
}


Expand Down
14 changes: 7 additions & 7 deletions g/net/ghttp/ghttp_server_admin_process.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func forkReloadProcess(newExeFilePath...string) error {
buffer, _ := gjson.Encode(sfm)
p.Env = append(p.Env, gADMIN_ACTION_RELOAD_ENVKEY + "=" + string(buffer))
if _, err := p.Start(); err != nil {
glog.Errorfln("%d: fork process failed, error:%s, %s", gproc.Pid(), err.Error(), string(buffer))
glog.Errorf("%d: fork process failed, error:%s, %s", gproc.Pid(), err.Error(), string(buffer))
return err
}
return nil
Expand All @@ -147,7 +147,7 @@ func forkRestartProcess(newExeFilePath...string) error {
env = append(env, gADMIN_ACTION_RESTART_ENVKEY + "=1")
p := gproc.NewProcess(path, os.Args, env)
if _, err := p.Start(); err != nil {
glog.Errorfln("%d: fork process failed, error:%s", gproc.Pid(), err.Error())
glog.Errorf("%d: fork process failed, error:%s", gproc.Pid(), err.Error())
return err
}
return nil
Expand Down Expand Up @@ -197,14 +197,14 @@ func restartWebServers(signal string, newExeFilePath...string) error {
}
} else {
if err := forkReloadProcess(newExeFilePath...); err != nil {
glog.Printfln("%d: server restarts failed", gproc.Pid())
glog.Printf("%d: server restarts failed", gproc.Pid())
serverProcessStatus.Set(gADMIN_ACTION_NONE)
return err
} else {
if len(signal) > 0 {
glog.Printfln("%d: server restarting by signal: %s", gproc.Pid(), signal)
glog.Printf("%d: server restarting by signal: %s", gproc.Pid(), signal)
} else {
glog.Printfln("%d: server restarting by web admin", gproc.Pid())
glog.Printf("%d: server restarting by web admin", gproc.Pid())
}

}
Expand All @@ -216,12 +216,12 @@ func restartWebServers(signal string, newExeFilePath...string) error {
func shutdownWebServers(signal...string) {
serverProcessStatus.Set(gADMIN_ACTION_SHUTINGDOWN)
if len(signal) > 0 {
glog.Printfln("%d: server shutting down by signal: %s", gproc.Pid(), signal[0])
glog.Printf("%d: server shutting down by signal: %s", gproc.Pid(), signal[0])
// 在终端信号下,立即执行关闭操作
forceCloseWebServers()
allDoneChan <- struct{}{}
} else {
glog.Printfln("%d: server shutting down by api", gproc.Pid())
glog.Printf("%d: server shutting down by api", gproc.Pid())
// 非终端信号下,异步1秒后再执行关闭,
// 目的是让接口能够正确返回结果,否则接口会报错(因为web server关闭了)
gtimer.SetTimeout(time.Second, func() {
Expand Down
6 changes: 3 additions & 3 deletions g/net/ghttp/ghttp_server_graceful.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (s *gracefulServer) doServe() error {
if s.fd != 0 {
action = "reloaded"
}
glog.Printfln("%d: %s server %s listening on [%s]", gproc.Pid(), s.getProto(), action, s.addr)
glog.Printf("%d: %s server %s listening on [%s]", gproc.Pid(), s.getProto(), action, s.addr)
s.status = SERVER_STATUS_RUNNING
err := s.httpServer.Serve(s.listener)
s.status = SERVER_STATUS_STOPPED
Expand Down Expand Up @@ -173,7 +173,7 @@ func (s *gracefulServer) shutdown() {
return
}
if err := s.httpServer.Shutdown(context.Background()); err != nil {
glog.Errorfln("%d: %s server [%s] shutdown error: %v", gproc.Pid(), s.getProto(), s.addr, err)
glog.Errorf("%d: %s server [%s] shutdown error: %v", gproc.Pid(), s.getProto(), s.addr, err)
}
}

Expand All @@ -183,7 +183,7 @@ func (s *gracefulServer) close() {
return
}
if err := s.httpServer.Close(); err != nil {
glog.Errorfln("%d: %s server [%s] closed error: %v", gproc.Pid(), s.getProto(), s.addr, err)
glog.Errorf("%d: %s server [%s] closed error: %v", gproc.Pid(), s.getProto(), s.addr, err)
}
}

2 changes: 1 addition & 1 deletion g/net/ghttp/ghttp_server_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func (s *Server) setHandler(pattern string, handler *handlerItem, hook ... strin
caller := s.getHandlerRegisterCallerLine(handler)
if len(hook) == 0 {
if item, ok := s.routesMap[regkey]; ok {
glog.Errorfln(`duplicated route registry "%s", already registered at %s`, pattern, item[0].file)
glog.Errorf(`duplicated route registry "%s", already registered at %s`, pattern, item[0].file)
return
}
}
Expand Down
6 changes: 3 additions & 3 deletions g/net/ghttp/ghttp_server_router_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (d *Domain) Group(prefix...string) *RouterGroup {
func (g *RouterGroup) Bind(items []GroupItem) {
for _, item := range items {
if len(item) < 3 {
glog.Fatalfln("invalid router item: %s", item)
glog.Fatalf("invalid router item: %s", item)
}
if strings.EqualFold(gconv.String(item[0]), "REST") {
g.bind("REST", gconv.String(item[0]) + ":" + gconv.String(item[1]), item[2])
Expand Down Expand Up @@ -124,7 +124,7 @@ func (g *RouterGroup) bind(bindType string, pattern string, object interface{},
if len(g.prefix) > 0 {
domain, method, path, err := g.server.parsePattern(pattern)
if err != nil {
glog.Fatalfln("invalid pattern: %s", pattern)
glog.Fatalf("invalid pattern: %s", pattern)
}
if bindType == "HANDLER" {
pattern = g.server.serveHandlerKey(method, g.prefix + "/" + strings.TrimLeft(path, "/"), domain)
Expand Down Expand Up @@ -196,7 +196,7 @@ func (g *RouterGroup) bind(bindType string, pattern string, object interface{},
g.domain.BindHookHandler(pattern, methods[0], h)
}
} else {
glog.Fatalfln("invalid hook handler for pattern:%s", pattern)
glog.Fatalf("invalid hook handler for pattern:%s", pattern)
}
}
}
Expand Down
Loading

0 comments on commit ebcc81c

Please sign in to comment.