merge master

This commit is contained in:
John
2018-11-03 16:00:22 +08:00
6 changed files with 58 additions and 57 deletions

View File

@ -40,9 +40,9 @@
- https://github.com/namreg/godown
- https://github.com/Masterminds/sprig
1. gform参考 https://gohouse.github.io/gorose/dist/index.html 进行改进
1. 模板引擎增加对象的支持(参考https://segmentfault.com/q/1010000016829214)
1. 模板引擎增加对象的支持(参考https://segmentfault.com/q/1010000016829214)
1. 由于系统对inotify实例数量(`fs.inotify.max_user_instances`)以及队列大小(`fs.inotify.max_user_watches`)有限制,需要改进`gfsnotify`
1. 改进gfpool在文件指针变化时的更新
# DONE

View File

@ -7,7 +7,6 @@
package gfile
import (
"gitee.com/johng/gf/g/os/gfpool"
"io"
"io/ioutil"
"os"
@ -35,7 +34,7 @@ func GetBinContents(path string) []byte {
}
// 写入文件内容
func putContents(path string, data []byte, flag int, perm os.FileMode) error {
func putContents(path string, data []byte, flag int, perm int) error {
// 支持目录递归创建
dir := Dir(path)
if !Exists(dir) {
@ -43,8 +42,8 @@ func putContents(path string, data []byte, flag int, perm os.FileMode) error {
return err
}
}
// 创建/打开文件使用文件指针池默认60秒
f, err := gfpool.OpenFile(path, flag, perm, gFILE_POOL_EXPIRE*1000)
// 创建/打开文件
f, err := OpenWithFlagPerm(path, flag, perm)
if err != nil {
return err
}
@ -103,11 +102,11 @@ func GetNextCharOffset(file *os.File, char byte, start int64) int64 {
// 获得文件内容下一个指定字节的位置
func GetNextCharOffsetByPath(path string, char byte, start int64) int64 {
if f, err := gfpool.Open(path, os.O_RDONLY, gDEFAULT_PERM, gFILE_POOL_EXPIRE*1000); err == nil {
if f, err := OpenWithFlagPerm(path, os.O_RDONLY, gDEFAULT_PERM); err == nil {
defer f.Close()
return GetNextCharOffset(&f.File, char, start)
return GetNextCharOffset(f, char, start)
} else {
// panic(err)
panic(err)
}
return -1
}
@ -122,11 +121,11 @@ func GetBinContentsTilChar(file *os.File, char byte, start int64) ([]byte, int64
// 获得文件内容直到下一个指定字节的位置(返回值包含该位置字符内容)
func GetBinContentsTilCharByPath(path string, char byte, start int64) ([]byte, int64) {
if f, err := gfpool.Open(path, os.O_RDONLY, gDEFAULT_PERM, gFILE_POOL_EXPIRE*1000); err == nil {
if f, err := OpenWithFlagPerm(path, os.O_RDONLY, gDEFAULT_PERM); err == nil {
defer f.Close()
return GetBinContentsTilChar(&f.File, char, start)
return GetBinContentsTilChar(f, char, start)
} else {
// panic(err)
panic(err)
}
return nil, -1
}
@ -142,11 +141,11 @@ func GetBinContentsByTwoOffsets(file *os.File, start int64, end int64) []byte {
// 获得文件内容中两个offset之间的内容 [start, end)
func GetBinContentsByTwoOffsetsByPath(path string, start int64, end int64) []byte {
if f, err := gfpool.Open(path, os.O_RDONLY, gDEFAULT_PERM, gFILE_POOL_EXPIRE*1000); err == nil {
if f, err := OpenWithFlagPerm(path, os.O_RDONLY, gDEFAULT_PERM); err == nil {
defer f.Close()
return GetBinContentsByTwoOffsets(&f.File, start, end)
return GetBinContentsByTwoOffsets(f, start, end)
} else {
// panic(err)
panic(err)
}
return nil
}

View File

@ -42,24 +42,32 @@ type File struct {
var pools = gmap.NewStringInterfaceMap()
// 获得文件对象,并自动创建指针池(过期时间单位:毫秒)
func Open(path string, flag int, perm os.FileMode, expire...int) (*File, error) {
func Open(path string, flag int, perm os.FileMode, expire...int) (file *File, err error) {
fpExpire := 0
if len(expire) > 0 {
fpExpire = expire[0]
}
pool := pools.GetOrSetFuncLock(fmt.Sprintf("%s&%d&%d&%d", path, flag, expire, perm), func() interface{} {
return New(path, flag, perm, fpExpire)
if p, e := New(path, flag, perm, fpExpire); e == nil {
return p
} else {
err = e
}
return nil
}).(*Pool)
if pool == nil {
return nil, err
}
return pool.File()
}
func OpenFile(path string, flag int, perm os.FileMode, expire...int) (*File, error) {
func OpenFile(path string, flag int, perm os.FileMode, expire...int) (file *File, err error) {
return Open(path, flag, perm, expire...)
}
// 创建一个文件指针池expire = 0表示不过期expire < 0表示使用完立即回收expire > 0表示超时回收默认值为0不过期
// 过期时间单位:毫秒
func New(path string, flag int, perm os.FileMode, expire...int) *Pool {
func New(path string, flag int, perm os.FileMode, expire...int) (*Pool, error) {
fpExpire := 0
if len(expire) > 0 {
fpExpire = expire[0]
@ -74,9 +82,9 @@ func New(path string, flag int, perm os.FileMode, expire...int) *Pool {
if watcher, err := fsnotify.NewWatcher(); err == nil {
p.watcher = watcher
} else {
return nil
return nil, err
}
return p
return p, nil
}
// 创建文件指针池

View File

@ -8,19 +8,18 @@
package glog
import (
"os"
"io"
"time"
"fmt"
"strings"
"runtime"
"gitee.com/johng/gf/g/os/gfile"
"gitee.com/johng/gf/g/util/gregex"
"gitee.com/johng/gf/g/container/gtype"
"gitee.com/johng/gf/g/os/gfile"
"gitee.com/johng/gf/g/os/gmlock"
"gitee.com/johng/gf/g/os/gfpool"
"sync"
"gitee.com/johng/gf/g/os/gtime"
"gitee.com/johng/gf/g/util/gregex"
"io"
"os"
"runtime"
"strings"
"sync"
"time"
)
type Logger struct {
@ -128,14 +127,14 @@ func (l *Logger) GetWriter() io.Writer {
}
// 获取默认的文件IO
func (l *Logger) getFilePointer() *gfpool.File {
func (l *Logger) getFilePointer() *os.File {
if path := l.path.Val(); path != "" {
// 文件名称中使用"{}"包含的内容使用gtime格式化
file, _ := gregex.ReplaceStringFunc(`{.+?}`, l.file.Val(), func(s string) string {
return gtime.Now().Format(strings.Trim(s, "{}"))
})
fpath := path + gfile.Separator + file
if fp, err := gfpool.Open(fpath, gDEFAULT_FILE_POOL_FLAGS, 0666); err == nil {
if fp, err := gfile.OpenWithFlagPerm(fpath, gDEFAULT_FILE_POOL_FLAGS, 0666); err == nil {
return fp
} else {
fmt.Fprintln(os.Stderr, err)
@ -249,20 +248,20 @@ func (l *Logger) GetBacktrace(skip...int) string {
from := 0
// 首先定位业务文件开始位置
for i := 0; i < 10; i++ {
if _, cfile, _, ok := runtime.Caller(i); ok {
if !gregex.IsMatchString("/g/os/glog/glog.+$", cfile) {
if _, file, _, ok := runtime.Caller(i); ok {
if !gregex.IsMatchString("/g/os/glog/glog.+$", file) {
from = i
break
}
}
}
// 从业务文件开始位置根据自定义的skip开始backtrace
goroot := runtime.GOROOT()
goRoot := runtime.GOROOT()
for i := from + customSkip + l.btSkip.Val(); i < 10000; i++ {
if _, cfile, cline, ok := runtime.Caller(i); ok && cfile != "" {
if _, file, cline, ok := runtime.Caller(i); ok && file != "" {
// 不打印出go源码路径及glog包文件路径日志打印必须从业务源码文件开始且从glog包文件开始检索
if (goroot == "" || !gregex.IsMatchString("^" + goroot, cfile)) && !gregex.IsMatchString(`<autogenerated>`, cfile) {
backtrace += fmt.Sprintf(`%d. %s:%d%s`, index, cfile, cline, ln)
if (goRoot == "" || !gregex.IsMatchString("^" + goRoot, file)) && !gregex.IsMatchString(`<autogenerated>`, file) {
backtrace += fmt.Sprintf(`%d. %s:%d%s`, index, file, cline, ln)
index++
}
} else {

View File

@ -1,21 +1,17 @@
package main
import (
"html/template"
"log"
"os"
"fmt"
"gitee.com/johng/gf/g/os/gtime"
"gitee.com/johng/gf/third/github.com/fsnotify/fsnotify"
)
type Person string
func (p Person) Label() string {
return "This is " + string(p)
}
func main() {
tmpl, err := template.New("").Parse(`{{sum 1 2 3}}`)
if err != nil {
log.Fatalf("Parse: %v", err)
if w, err := fsnotify.NewWatcher(); err != nil {
fmt.Println(err)
} else {
fmt.Println(gtime.Now().String())
w.Add("/tmp/test")
}
tmpl.Execute(os.Stdout, nil)
}

View File

@ -1,12 +1,11 @@
package main
import (
"fmt"
"gitee.com/johng/gf/g/util/gregex"
"gitee.com/johng/gf/g/container/garray"
)
func main() {
s := `[0-9][0-9]/Jan/[0-9][0-9][0-9][0-9]:[0-9][0-9]:[0-9][0-9]:[0-9][0-9] \+[0-9][0-9][0-9][0-9]`
s,_ = gregex.ReplaceString(`[A-Za-z]`, `[A-Za-z]`, s)
fmt.Println(s)
a := garray.NewSortedIntArray(0)
a.Add(1)
a.Remove(0)
}