This commit is contained in:
liwei 2022-08-08 14:06:27 +08:00
commit c6a2bf7dd8
91 changed files with 3159 additions and 5422 deletions

14
go.mod
View File

@ -12,12 +12,9 @@ require (
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/golang/protobuf v1.5.2
github.com/gorilla/websocket v1.4.2
github.com/hashicorp/consul/api v1.12.0
github.com/json-iterator/go v1.1.12
github.com/mitchellh/hashstructure v1.1.0
github.com/modern-go/reflect2 v1.0.2
github.com/nacos-group/nacos-sdk-go v1.0.8
github.com/natefinch/lumberjack v2.0.0+incompatible
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475
github.com/robfig/cron/v3 v3.0.1
github.com/rs/xid v1.3.0
@ -31,7 +28,7 @@ require (
github.com/ugorji/go/codec v1.2.7
github.com/valyala/fastrand v1.1.0
go.mongodb.org/mongo-driver v1.5.1
go.uber.org/zap v1.21.0
go.uber.org/multierr v1.6.0
golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3
google.golang.org/protobuf v1.28.0
gopkg.in/yaml.v2 v2.4.0
@ -39,11 +36,9 @@ require (
require (
github.com/akutz/memconn v0.1.0 // indirect
github.com/aliyun/alibaba-cloud-sdk-go v1.61.885 // indirect
github.com/apache/thrift v0.16.0 // indirect
github.com/armon/go-metrics v0.3.10 // indirect
github.com/aws/aws-sdk-go v1.34.28 // indirect
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 // indirect
github.com/cenk/backoff v2.2.1+incompatible // indirect
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
@ -54,7 +49,6 @@ require (
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/go-errors/errors v1.0.1 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ping/ping v0.0.0-20211130115550-779d1e919534 // indirect
@ -67,6 +61,7 @@ require (
github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/grandcat/zeroconf v1.0.0 // indirect
github.com/hashicorp/consul/api v1.12.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-hclog v1.2.0 // indirect
@ -113,7 +108,6 @@ require (
github.com/tidwall/pretty v1.2.0 // indirect
github.com/tinylib/msgp v1.1.6 // indirect
github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
@ -125,7 +119,7 @@ require (
go.opentelemetry.io/otel v1.6.3 // indirect
go.opentelemetry.io/otel/trace v1.6.3 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.21.0 // indirect
golang.org/x/crypto v0.0.0-20220408190544-5352b0902921 // indirect
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
@ -133,8 +127,6 @@ require (
golang.org/x/text v0.3.7 // indirect
golang.org/x/tools v0.1.10 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
)

17
go.sum
View File

@ -44,7 +44,6 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/ChimeraCoder/gojson v1.1.0/go.mod h1:nYbTQlu6hv8PETM15J927yM0zGj3njIldp72UT1MqSw=
@ -58,8 +57,6 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk=
github.com/aliyun/alibaba-cloud-sdk-go v1.61.885 h1:H7Mq9zsKIMvBaw7rEmbWULvSTF2UI/9lFvvm4d/NZdk=
github.com/aliyun/alibaba-cloud-sdk-go v1.61.885/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/apache/thrift v0.16.0 h1:qEy6UW60iVOlUy+b9ZR0d5WzUWYGOo4HfopoyBaNmoY=
@ -83,7 +80,6 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 h1:D21IyuvjDCshj1/qq+pCNd3VZOAEI9jy6Bi131YlXgI=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/cenk/backoff v2.2.1+incompatible h1:djdFT7f4gF2ttuzRKPbMOWgZajgesItGLwG5FTQKmmE=
github.com/cenk/backoff v2.2.1+incompatible/go.mod h1:7FtoeaSnHoZnmZzz47cM35Y9nSW7tNyaidugnHTaFDE=
@ -146,7 +142,6 @@ github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWp
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@ -292,7 +287,6 @@ github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
@ -385,7 +379,6 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/juju/ratelimit v1.0.1 h1:+7AIFJVQ0EQgq/K9+0Krm7m530Du7tIz0METWzN0RgY=
github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=
@ -476,8 +469,6 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/hashstructure v1.1.0 h1:P6P1hdjqAAknpY/M1CGipelZgp+4y9ja9kmUZPXP+H0=
github.com/mitchellh/hashstructure v1.1.0/go.mod h1:xUDAozZz0Wmdiufv0uyhnHkUTN6/6d8ulp4AwfLKrmA=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
@ -495,8 +486,6 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJ
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nacos-group/nacos-sdk-go v1.0.8 h1:8pEm05Cdav9sQgJSv5kyvlgfz0SzFUUGI3pWX6SiSnM=
github.com/nacos-group/nacos-sdk-go v1.0.8/go.mod h1:hlAPn3UdzlxIlSILAyOXKxjFSvDJ9oLzTJ9hLAK1KzA=
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
@ -617,10 +606,8 @@ github.com/smallnest/quick v0.0.0-20220103065406-780def6371e6 h1:J8xk0QMMrqfDLqU
github.com/smallnest/quick v0.0.0-20220103065406-780def6371e6/go.mod h1:h+J5yoLzf3XMKtM9l4vOaUtS4e+si6T3sKDtheJ15wc=
github.com/smallnest/rpcx v1.7.4 h1:u6ADk/Ep8BqtAoJZO7LbniWsP+nqeAtcbaPm2D4eOXg=
github.com/smallnest/rpcx v1.7.4/go.mod h1:TSciUoPlm8MYxnC7ErCz5ZymOFxOTbhN9cRgEI6Degs=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
@ -668,7 +655,6 @@ github.com/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw=
github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw=
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 h1:kF/7m/ZU+0D4Jj5eZ41Zm3IH/J8OElK1Qtd7tVKAwLk=
github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3/go.mod h1:QDlpd3qS71vYtakd2hmdpqhJ9nwv6mD6A30bQ1BPBFE=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
@ -1167,10 +1153,7 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -8,7 +8,6 @@ import (
"go_dreamfactory/lego/base"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/core/cbase"
"go_dreamfactory/lego/sys/codec"
"go_dreamfactory/lego/sys/event"
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/lego/sys/rpcx"
@ -85,12 +84,6 @@ func (this *RPCXService) InitSys() {
} else {
log.Infof("Sys event Init success !")
}
//初始化编码Codec
if err := codec.OnInit(this.opts.Setting.Sys["codec"]); err != nil {
log.Panicf(fmt.Sprintf("Sys codec Init err:%v", err))
} else {
log.Infof("Sys codec Init success !")
}
//初始化rpcx系统
if err := rpcx.OnInit(this.opts.Setting.Sys["rpcx"], rpcx.SetServiceTag(this.GetTag()), rpcx.SetServiceId(this.GetId()), rpcx.SetServiceType(this.GetType()), rpcx.SetServiceVersion(this.GetVersion()), rpcx.SetServiceAddr(fmt.Sprintf("%s:%d", this.GetIp(), this.GetPort()))); err != nil {
log.Panicf(fmt.Sprintf("Sys rpcx Init err:%v", err))

View File

@ -1,134 +0,0 @@
package blockcache
import (
"sync"
"sync/atomic"
"unsafe"
"go_dreamfactory/lego/utils/container"
)
func newSys(options Options) (sys *Cache, err error) {
sys = &Cache{
options: options,
inpip: make(chan interface{}),
outpip: make(chan interface{}),
outnotic: make(chan struct{}),
element: container.NewLKQueue(),
free: options.CacheMaxSzie,
}
go sys.run()
return
}
type Item struct {
Size int64
Value interface{}
}
type Cache struct {
options Options
inpip chan interface{}
outpip chan interface{}
outnotic chan struct{}
instate int32
outruning int32
element *container.LKQueue
free int64
close int32
wg sync.WaitGroup
}
func (this *Cache) In() chan<- interface{} {
return this.inpip
}
func (this *Cache) Out() <-chan interface{} {
return this.outpip
}
func (this *Cache) Close() {
atomic.StoreInt32(&this.close, 1)
close(this.inpip)
close(this.outnotic)
this.wg.Wait()
close(this.outpip)
}
func (this *Cache) run() {
for v := range this.inpip {
siez := int64(unsafe.Sizeof(v))
if siez > this.options.CacheMaxSzie { //异常数据
this.Errorf("item size:%d large CacheMaxSzie:%d", siez, this.options.CacheMaxSzie)
continue
} else if siez > atomic.LoadInt64(&this.free) { //空间不足
atomic.StoreInt32(&this.instate, 1)
locp:
for _ = range this.outnotic {
if siez > atomic.LoadInt64(&this.free) {
atomic.StoreInt32(&this.instate, 1)
} else {
this.element.Enqueue(&Item{Size: siez, Value: v})
atomic.AddInt64(&this.free, -1*siez)
break locp
}
}
} else {
this.element.Enqueue(&Item{Size: siez, Value: v})
atomic.AddInt64(&this.free, -1*siez)
}
if atomic.CompareAndSwapInt32(&this.outruning, 0, 1) {
this.wg.Add(1)
go func() {
locp:
for {
v := this.element.Dequeue()
if v != nil && atomic.LoadInt32(&this.close) == 0 {
item := v.(*Item)
atomic.AddInt64(&this.free, item.Size)
if atomic.CompareAndSwapInt32(&this.instate, 1, 0) {
this.outnotic <- struct{}{}
}
this.outpip <- item.Value
} else {
break locp
}
}
atomic.StoreInt32(&this.outruning, 0)
this.wg.Done()
}()
}
}
}
///日志***********************************************************************
func (this *Cache) Debugf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Debugf("[SYS BlockCache] "+format, a)
}
}
func (this *Cache) Infof(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Infof("[SYS BlockCache] "+format, a)
}
}
func (this *Cache) Warnf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Warnf("[SYS BlockCache] "+format, a)
}
}
func (this *Cache) Errorf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Errorf("[SYS BlockCache] "+format, a)
}
}
func (this *Cache) Panicf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Panicf("[SYS BlockCache] "+format, a)
}
}
func (this *Cache) Fatalf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Fatalf("[SYS BlockCache] "+format, a)
}
}

View File

@ -1,44 +0,0 @@
package blockcache
/*
限容堵塞缓冲池系统
设置最大内存大小 当缓存区为存满是直接写入 写满后进入堵塞状态 等待缓存区释放
*/
type (
ISys interface {
In() chan<- interface{}
Out() <-chan interface{}
Close()
}
)
var (
defsys ISys
)
func OnInit(config map[string]interface{}, option ...Option) (err error) {
if defsys, err = newSys(newOptions(config, option...)); err == nil {
}
return
}
func NewSys(option ...Option) (sys ISys, err error) {
if sys, err = newSys(newOptionsByOption(option...)); err == nil {
}
return
}
func In() chan<- interface{} {
return defsys.In()
}
func Out() <-chan interface{} {
return defsys.Out()
}
func Close() {
defsys.Close()
}

View File

@ -1,57 +0,0 @@
package blockcache
import (
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/lego/utils/mapstructure"
)
type Option func(*Options)
type Options struct {
CacheMaxSzie int64
Debug bool //日志是否开启
Log log.ILog
}
func SetCacheMaxSzie(v int64) Option {
return func(o *Options) {
o.CacheMaxSzie = v
}
}
func SetDebug(v bool) Option {
return func(o *Options) {
o.Debug = v
}
}
func SetLog(v log.ILog) Option {
return func(o *Options) {
o.Log = v
}
}
func newOptions(config map[string]interface{}, opts ...Option) Options {
options := Options{
CacheMaxSzie: 1024 * 1024 * 100,
Debug: true,
Log: log.Clone(log.SetLoglayer(2)),
}
if config != nil {
mapstructure.Decode(config, &options)
}
for _, o := range opts {
o(&options)
}
return options
}
func newOptionsByOption(opts ...Option) Options {
options := Options{
CacheMaxSzie: 1024 * 1024 * 100,
Debug: true,
Log: log.Clone(log.SetLoglayer(2)),
}
for _, o := range opts {
o(&options)
}
return options
}

View File

@ -1,58 +0,0 @@
package blockcache_test
import (
"fmt"
"os"
"os/signal"
"syscall"
"testing"
"time"
"go_dreamfactory/lego/sys/blockcache"
"go_dreamfactory/lego/sys/log"
)
func Test_sys(t *testing.T) {
if err := log.OnInit(nil, log.SetLoglevel(log.DebugLevel), log.SetDebugMode(true)); err != nil {
fmt.Printf("log init err:%v", err)
return
}
log.Debugf("log init succ")
if sys, err := blockcache.NewSys(blockcache.SetCacheMaxSzie(100)); err != nil {
log.Debugf("livego init err:%v", err)
return
} else {
closeSignal := make(chan struct{})
go func() {
locp:
for {
select {
case <-closeSignal:
break locp
default:
sys.In() <- "liwei1dao"
log.Debugf("In:liwei1dao")
}
}
log.Debugf("In:End")
}()
go func() {
for v := range sys.Out() {
log.Debugf("Out:%v", v)
time.Sleep(time.Second)
}
log.Debugf("Out:End")
}()
go func() {
time.Sleep(time.Second * 3)
closeSignal <- struct{}{}
sys.Close()
}()
}
sigterm := make(chan os.Signal, 1)
signal.Notify(sigterm, syscall.SIGINT, syscall.SIGTERM)
select {
case <-sigterm:
fmt.Printf("terminating: via signal\n")
}
}

View File

@ -1,820 +0,0 @@
package cachego
import (
"encoding/gob"
"fmt"
"io"
"os"
"time"
)
func (this *CacheGo) SetDefault(k string, x interface{}) {
this.Set(k, x, this.options.Expiration)
}
func (this *CacheGo) Replace(k string, x interface{}, d time.Duration) error {
this.mu.Lock()
_, found := this.get(k)
if !found {
this.mu.Unlock()
return fmt.Errorf("Item %s doesn't exist", k)
}
this.set(k, x, d)
this.mu.Unlock()
return nil
}
func (this *CacheGo) GetWithExpiration(k string) (interface{}, time.Time, bool) {
this.mu.RLock()
// "Inlining" of get and Expired
item, found := this.items[k]
if !found {
this.mu.RUnlock()
return nil, time.Time{}, false
}
if item.Expiration > 0 {
if time.Now().UnixNano() > item.Expiration {
this.mu.RUnlock()
return nil, time.Time{}, false
}
// Return the item and the expiration time
this.mu.RUnlock()
return item.Object, time.Unix(0, item.Expiration), true
}
// If expiration <= 0 (i.e. no expiration time set) then return the item
// and a zeroed time.Time
this.mu.RUnlock()
return item.Object, time.Time{}, true
}
func (this *CacheGo) Increment(k string, n int64) error {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return fmt.Errorf("Item %s not found", k)
}
switch v.Object.(type) {
case int:
v.Object = v.Object.(int) + int(n)
case int8:
v.Object = v.Object.(int8) + int8(n)
case int16:
v.Object = v.Object.(int16) + int16(n)
case int32:
v.Object = v.Object.(int32) + int32(n)
case int64:
v.Object = v.Object.(int64) + n
case uint:
v.Object = v.Object.(uint) + uint(n)
case uintptr:
v.Object = v.Object.(uintptr) + uintptr(n)
case uint8:
v.Object = v.Object.(uint8) + uint8(n)
case uint16:
v.Object = v.Object.(uint16) + uint16(n)
case uint32:
v.Object = v.Object.(uint32) + uint32(n)
case uint64:
v.Object = v.Object.(uint64) + uint64(n)
case float32:
v.Object = v.Object.(float32) + float32(n)
case float64:
v.Object = v.Object.(float64) + float64(n)
default:
this.mu.Unlock()
return fmt.Errorf("The value for %s is not an integer", k)
}
this.items[k] = v
this.mu.Unlock()
return nil
}
func (this *CacheGo) IncrementFloat(k string, n float64) error {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return fmt.Errorf("Item %s not found", k)
}
switch v.Object.(type) {
case float32:
v.Object = v.Object.(float32) + float32(n)
case float64:
v.Object = v.Object.(float64) + n
default:
this.mu.Unlock()
return fmt.Errorf("The value for %s does not have type float32 or float64", k)
}
this.items[k] = v
this.mu.Unlock()
return nil
}
func (this *CacheGo) IncrementInt(k string, n int) (int, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an int", k)
}
nv := rv + n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) IncrementInt8(k string, n int8) (int8, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int8)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an int8", k)
}
nv := rv + n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) IncrementInt16(k string, n int16) (int16, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int16)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an int16", k)
}
nv := rv + n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) IncrementInt32(k string, n int32) (int32, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int32)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an int32", k)
}
nv := rv + n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) IncrementInt64(k string, n int64) (int64, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int64)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an int64", k)
}
nv := rv + n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) IncrementUint(k string, n uint) (uint, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint", k)
}
nv := rv + n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) IncrementUintptr(k string, n uintptr) (uintptr, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uintptr)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an uintptr", k)
}
nv := rv + n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) IncrementUint8(k string, n uint8) (uint8, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint8)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint8", k)
}
nv := rv + n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) IncrementUint16(k string, n uint16) (uint16, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint16)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint16", k)
}
nv := rv + n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) IncrementUint32(k string, n uint32) (uint32, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint32)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint32", k)
}
nv := rv + n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) IncrementUint64(k string, n uint64) (uint64, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint64)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint64", k)
}
nv := rv + n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) IncrementFloat32(k string, n float32) (float32, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(float32)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an float32", k)
}
nv := rv + n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) IncrementFloat64(k string, n float64) (float64, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(float64)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an float64", k)
}
nv := rv + n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) Decrement(k string, n int64) error {
// TODO: Implement Increment and Decrement more cleanly.
// (Cannot do Increment(k, n*-1) for uints.)
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return fmt.Errorf("Item not found")
}
switch v.Object.(type) {
case int:
v.Object = v.Object.(int) - int(n)
case int8:
v.Object = v.Object.(int8) - int8(n)
case int16:
v.Object = v.Object.(int16) - int16(n)
case int32:
v.Object = v.Object.(int32) - int32(n)
case int64:
v.Object = v.Object.(int64) - n
case uint:
v.Object = v.Object.(uint) - uint(n)
case uintptr:
v.Object = v.Object.(uintptr) - uintptr(n)
case uint8:
v.Object = v.Object.(uint8) - uint8(n)
case uint16:
v.Object = v.Object.(uint16) - uint16(n)
case uint32:
v.Object = v.Object.(uint32) - uint32(n)
case uint64:
v.Object = v.Object.(uint64) - uint64(n)
case float32:
v.Object = v.Object.(float32) - float32(n)
case float64:
v.Object = v.Object.(float64) - float64(n)
default:
this.mu.Unlock()
return fmt.Errorf("The value for %s is not an integer", k)
}
this.items[k] = v
this.mu.Unlock()
return nil
}
func (this *CacheGo) DecrementFloat(k string, n float64) error {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return fmt.Errorf("Item %s not found", k)
}
switch v.Object.(type) {
case float32:
v.Object = v.Object.(float32) - float32(n)
case float64:
v.Object = v.Object.(float64) - n
default:
this.mu.Unlock()
return fmt.Errorf("The value for %s does not have type float32 or float64", k)
}
this.items[k] = v
this.mu.Unlock()
return nil
}
func (this *CacheGo) DecrementInt(k string, n int) (int, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an int", k)
}
nv := rv - n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) DecrementInt8(k string, n int8) (int8, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int8)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an int8", k)
}
nv := rv - n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) DecrementInt16(k string, n int16) (int16, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int16)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an int16", k)
}
nv := rv - n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) DecrementInt32(k string, n int32) (int32, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int32)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an int32", k)
}
nv := rv - n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) DecrementInt64(k string, n int64) (int64, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(int64)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an int64", k)
}
nv := rv - n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) DecrementUint(k string, n uint) (uint, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint", k)
}
nv := rv - n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) DecrementUintptr(k string, n uintptr) (uintptr, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uintptr)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an uintptr", k)
}
nv := rv - n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) DecrementUint8(k string, n uint8) (uint8, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint8)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint8", k)
}
nv := rv - n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) DecrementUint16(k string, n uint16) (uint16, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint16)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint16", k)
}
nv := rv - n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) DecrementUint32(k string, n uint32) (uint32, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint32)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint32", k)
}
nv := rv - n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) DecrementUint64(k string, n uint64) (uint64, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(uint64)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an uint64", k)
}
nv := rv - n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) DecrementFloat32(k string, n float32) (float32, error) {
this.mu.Lock()
v, found := this.items[k]
if !found || v.Expired() {
this.mu.Unlock()
return 0, fmt.Errorf("Item %s not found", k)
}
rv, ok := v.Object.(float32)
if !ok {
this.mu.Unlock()
return 0, fmt.Errorf("The value for %s is not an float32", k)
}
nv := rv - n
v.Object = nv
this.items[k] = v
this.mu.Unlock()
return nv, nil
}
func (this *CacheGo) OnEvicted(f func(string, interface{})) {
this.mu.Lock()
this.onEvicted = f
this.mu.Unlock()
}
func (this *CacheGo) Set(k string, x interface{}, d time.Duration) {
var e int64
if d > 0 {
e = time.Now().Add(d).UnixNano()
}
this.mu.Lock()
this.items[k] = Item{
Object: x,
Expiration: e,
}
this.mu.Unlock()
}
func (this *CacheGo) Add(k string, x interface{}, d time.Duration) error {
this.mu.Lock()
_, found := this.get(k)
if found {
this.mu.Unlock()
return fmt.Errorf("Item %s already exists", k)
}
this.set(k, x, d)
this.mu.Unlock()
return nil
}
func (this *CacheGo) DeleteExpired() {
var evictedItems []keyAndValue
now := time.Now().UnixNano()
this.mu.Lock()
for k, v := range this.items {
// "Inlining" of expired
if v.Expiration > 0 && now > v.Expiration {
ov, evicted := this.delete(k)
if evicted {
evictedItems = append(evictedItems, keyAndValue{k, ov})
}
}
}
this.mu.Unlock()
for _, v := range evictedItems {
this.onEvicted(v.key, v.value)
}
}
func (this *CacheGo) SaveFile(fname string) error {
fp, err := os.Create(fname)
if err != nil {
return err
}
err = this.Save(fp)
if err != nil {
fp.Close()
return err
}
return fp.Close()
}
func (this *CacheGo) Save(w io.Writer) (err error) {
enc := gob.NewEncoder(w)
defer func() {
if x := recover(); x != nil {
err = fmt.Errorf("Error registering item types with Gob library")
}
}()
this.mu.RLock()
defer this.mu.RUnlock()
for _, v := range this.items {
gob.Register(v.Object)
}
err = enc.Encode(&this.items)
return
}
func (this *CacheGo) Load(r io.Reader) error {
dec := gob.NewDecoder(r)
items := map[string]Item{}
err := dec.Decode(&items)
if err == nil {
this.mu.Lock()
defer this.mu.Unlock()
for k, v := range items {
ov, found := this.items[k]
if !found || ov.Expired() {
this.items[k] = v
}
}
}
return err
}
func (this *CacheGo) LoadFile(fname string) error {
fp, err := os.Open(fname)
if err != nil {
return err
}
err = this.Load(fp)
if err != nil {
fp.Close()
return err
}
return fp.Close()
}
func (this *CacheGo) Items() map[string]Item {
this.mu.RLock()
defer this.mu.RUnlock()
m := make(map[string]Item, len(this.items))
now := time.Now().UnixNano()
for k, v := range this.items {
if v.Expiration > 0 {
if now > v.Expiration {
continue
}
}
m[k] = v
}
return m
}
func (this *CacheGo) ItemCount() int {
this.mu.RLock()
n := len(this.items)
this.mu.RUnlock()
return n
}
func (this *CacheGo) Flush() {
this.mu.Lock()
this.items = map[string]Item{}
this.mu.Unlock()
}
func (this *CacheGo) get(k string) (interface{}, bool) {
item, found := this.items[k]
if !found {
return nil, false
}
// "Inlining" of Expired
if item.Expiration > 0 {
if time.Now().UnixNano() > item.Expiration {
return nil, false
}
}
return item.Object, true
}
func (this *CacheGo) set(k string, x interface{}, d time.Duration) {
var e int64
if d > 0 {
e = time.Now().Add(d).UnixNano()
}
this.items[k] = Item{
Object: x,
Expiration: e,
}
}
func (this *CacheGo) delete(k string) (interface{}, bool) {
if this.onEvicted != nil {
if v, found := this.items[k]; found {
delete(this.items, k)
return v.Object, true
}
}
delete(this.items, k)
return nil, false
}

View File

@ -1,47 +0,0 @@
package cachego
import (
"sync"
"time"
)
func newSys(options Options) (sys *CacheGo, err error) {
sys = &CacheGo{
options: options,
items: make(map[string]Item),
}
err = sys.init()
return
}
type CacheGo struct {
options Options
items map[string]Item
mu sync.RWMutex
onEvicted func(string, interface{})
stop chan bool
}
func (this *CacheGo) init() (err error) {
if this.options.CleanupInterval > 0 {
go this.run()
}
return
}
func (this *CacheGo) run() {
ticker := time.NewTicker(time.Duration(this.options.CleanupInterval) * time.Second)
for {
select {
case <-ticker.C:
this.DeleteExpired()
case <-this.stop:
ticker.Stop()
return
}
}
}
func (this *CacheGo) Clsoe() {
this.stop <- true
}

View File

@ -1,187 +0,0 @@
package cachego
/*
本地缓存系统
*/
import (
"io"
"time"
)
type (
ISys interface {
Flush()
ItemCount() int
Items() map[string]Item
SaveFile(fname string) error
Save(w io.Writer) (err error)
Load(r io.Reader) error
LoadFile(fname string) error
Add(k string, x interface{}, d time.Duration) error
Set(k string, x interface{}, d time.Duration)
OnEvicted(f func(string, interface{}))
Increment(k string, n int64) error
IncrementFloat(k string, n float64) error
IncrementInt(k string, n int) (int, error)
IncrementInt8(k string, n int8) (int8, error)
IncrementInt16(k string, n int16) (int16, error)
IncrementInt32(k string, n int32) (int32, error)
IncrementInt64(k string, n int64) (int64, error)
IncrementUint(k string, n uint) (uint, error)
IncrementUintptr(k string, n uintptr) (uintptr, error)
IncrementUint8(k string, n uint8) (uint8, error)
IncrementUint16(k string, n uint16) (uint16, error)
IncrementUint32(k string, n uint32) (uint32, error)
IncrementUint64(k string, n uint64) (uint64, error)
IncrementFloat32(k string, n float32) (float32, error)
IncrementFloat64(k string, n float64) (float64, error)
Decrement(k string, n int64) error
DecrementFloat(k string, n float64) error
DecrementInt(k string, n int) (int, error)
DecrementInt8(k string, n int8) (int8, error)
DecrementInt16(k string, n int16) (int16, error)
DecrementInt32(k string, n int32) (int32, error)
DecrementInt64(k string, n int64) (int64, error)
DecrementUint(k string, n uint) (uint, error)
DecrementUintptr(k string, n uintptr) (uintptr, error)
DecrementUint8(k string, n uint8) (uint8, error)
DecrementUint16(k string, n uint16) (uint16, error)
DecrementUint32(k string, n uint32) (uint32, error)
DecrementUint64(k string, n uint64) (uint64, error)
DecrementFloat32(k string, n float32) (float32, error)
}
)
var (
defsys ISys
)
func OnInit(config map[string]interface{}, option ...Option) (err error) {
if defsys, err = newSys(newOptions(config, option...)); err == nil {
}
return
}
func NewSys(option ...Option) (sys ISys, err error) {
if sys, err = newSys(newOptionsByOption(option...)); err == nil {
}
return
}
func Flush() {
defsys.Flush()
}
func ItemCount() int {
return defsys.ItemCount()
}
func Items() map[string]Item {
return defsys.Items()
}
func SaveFile(fname string) error {
return defsys.SaveFile(fname)
}
func Save(w io.Writer) (err error) {
return defsys.Save(w)
}
func Load(r io.Reader) error {
return defsys.Load(r)
}
func LoadFile(fname string) error {
return defsys.LoadFile(fname)
}
func Add(k string, x interface{}, d time.Duration) error {
return defsys.Add(k, x, d)
}
func Set(k string, x interface{}, d time.Duration) {
defsys.Set(k, x, d)
}
func OnEvicted(f func(string, interface{})) {
defsys.OnEvicted(f)
}
func Increment(k string, n int64) error {
return defsys.Increment(k, n)
}
func IncrementFloat(k string, n float64) error {
return defsys.IncrementFloat(k, n)
}
func IncrementInt(k string, n int) (int, error) {
return defsys.IncrementInt(k, n)
}
func IncrementInt8(k string, n int8) (int8, error) {
return defsys.IncrementInt8(k, n)
}
func IncrementInt16(k string, n int16) (int16, error) {
return defsys.IncrementInt16(k, n)
}
func IncrementInt32(k string, n int32) (int32, error) {
return defsys.IncrementInt32(k, n)
}
func IncrementInt64(k string, n int64) (int64, error) {
return defsys.IncrementInt64(k, n)
}
func IncrementUint(k string, n uint) (uint, error) {
return defsys.IncrementUint(k, n)
}
func IncrementUintptr(k string, n uintptr) (uintptr, error) {
return defsys.IncrementUintptr(k, n)
}
func IncrementUint8(k string, n uint8) (uint8, error) {
return defsys.IncrementUint8(k, n)
}
func IncrementUint16(k string, n uint16) (uint16, error) {
return defsys.IncrementUint16(k, n)
}
func IncrementUint32(k string, n uint32) (uint32, error) {
return defsys.IncrementUint32(k, n)
}
func IncrementUint64(k string, n uint64) (uint64, error) {
return defsys.IncrementUint64(k, n)
}
func IncrementFloat32(k string, n float32) (float32, error) {
return defsys.IncrementFloat32(k, n)
}
func IncrementFloat64(k string, n float64) (float64, error) {
return defsys.IncrementFloat64(k, n)
}
func Decrement(k string, n int64) error {
return defsys.Decrement(k, n)
}
func DecrementFloat(k string, n float64) error {
return defsys.DecrementFloat(k, n)
}
func DecrementInt(k string, n int) (int, error) {
return defsys.DecrementInt(k, n)
}
func DecrementInt8(k string, n int8) (int8, error) {
return defsys.DecrementInt8(k, n)
}
func DecrementInt16(k string, n int16) (int16, error) {
return defsys.DecrementInt16(k, n)
}
func DecrementInt32(k string, n int32) (int32, error) {
return defsys.DecrementInt32(k, n)
}
func DecrementInt64(k string, n int64) (int64, error) {
return defsys.DecrementInt64(k, n)
}
func DecrementUint(k string, n uint) (uint, error) {
return defsys.DecrementUint(k, n)
}
func DecrementUintptr(k string, n uintptr) (uintptr, error) {
return defsys.DecrementUintptr(k, n)
}
func DecrementUint8(k string, n uint8) (uint8, error) {
return defsys.DecrementUint8(k, n)
}
func DecrementUint16(k string, n uint16) (uint16, error) {
return defsys.DecrementUint16(k, n)
}
func DecrementUint32(k string, n uint32) (uint32, error) {
return defsys.DecrementUint32(k, n)
}
func DecrementUint64(k string, n uint64) (uint64, error) {
return defsys.DecrementUint64(k, n)
}
func DecrementFloat32(k string, n float32) (float32, error) {
return defsys.DecrementFloat32(k, n)
}

View File

@ -1,19 +0,0 @@
package cachego
import "time"
type keyAndValue struct {
key string
value interface{}
}
type Item struct {
Object interface{}
Expiration int64
}
func (item Item) Expired() bool {
if item.Expiration == 0 {
return false
}
return time.Now().UnixNano() > item.Expiration
}

View File

@ -1,38 +0,0 @@
package cachego
import (
"time"
"go_dreamfactory/lego/utils/mapstructure"
)
type Option func(*Options)
type Options struct {
Expiration time.Duration
CleanupInterval time.Duration
}
func newOptions(config map[string]interface{}, opts ...Option) Options {
options := Options{
Expiration: -1,
CleanupInterval: 0,
}
if config != nil {
mapstructure.Decode(config, &options)
}
for _, o := range opts {
o(&options)
}
return options
}
func newOptionsByOption(opts ...Option) Options {
options := Options{
Expiration: -1,
CleanupInterval: 0,
}
for _, o := range opts {
o(&options)
}
return options
}

View File

@ -1,273 +0,0 @@
package codec
import (
"errors"
"fmt"
"reflect"
"sync"
"go_dreamfactory/lego/sys/codec/core"
"go_dreamfactory/lego/sys/codec/factory"
"go_dreamfactory/lego/sys/codec/render"
"github.com/modern-go/reflect2"
)
func newSys(options core.Options) (sys *Codec, err error) {
sys = &Codec{
options: &options,
decoderCache: new(sync.Map),
encoderCache: new(sync.Map),
streamPool: &sync.Pool{
New: func() interface{} {
return render.NewStream(sys, 512)
},
},
extraPool: &sync.Pool{
New: func() interface{} {
return render.NewExtractor(sys)
},
},
}
return
}
type Codec struct {
options *core.Options
decoderCache *sync.Map
encoderCache *sync.Map
streamPool *sync.Pool
extraPool *sync.Pool
}
func (this *Codec) Options() *core.Options {
return this.options
}
func (this *Codec) addDecoderToCache(cacheKey uintptr, decoder core.IDecoder) {
this.decoderCache.Store(cacheKey, decoder)
}
func (this *Codec) addEncoderToCache(cacheKey uintptr, encoder core.IEncoder) {
this.encoderCache.Store(cacheKey, encoder)
}
func (this *Codec) GetEncoderFromCache(cacheKey uintptr) core.IEncoder {
encoder, found := this.encoderCache.Load(cacheKey)
if found {
return encoder.(core.IEncoder)
}
return nil
}
func (this *Codec) GetDecoderFromCache(cacheKey uintptr) core.IDecoder {
decoder, found := this.decoderCache.Load(cacheKey)
if found {
return decoder.(core.IDecoder)
}
return nil
}
func (this *Codec) EncoderOf(typ reflect2.Type) core.IEncoder {
cacheKey := typ.RType()
encoder := this.GetEncoderFromCache(cacheKey)
if encoder != nil {
return encoder
}
ctx := &core.Ctx{
ICodec: this,
Prefix: "",
Decoders: map[reflect2.Type]core.IDecoder{},
Encoders: map[reflect2.Type]core.IEncoder{},
}
encoder = factory.EncoderOfType(ctx, typ)
if typ.LikePtr() {
encoder = factory.NewonePtrEncoder(encoder)
}
this.addEncoderToCache(cacheKey, encoder)
return encoder
}
func (this *Codec) DecoderOf(typ reflect2.Type) core.IDecoder {
cacheKey := typ.RType()
decoder := this.GetDecoderFromCache(cacheKey)
if decoder != nil {
return decoder
}
ctx := &core.Ctx{
ICodec: this,
Prefix: "",
Decoders: map[reflect2.Type]core.IDecoder{},
Encoders: map[reflect2.Type]core.IEncoder{},
}
ptrType := typ.(*reflect2.UnsafePtrType)
decoder = factory.DecoderOfType(ctx, ptrType.Elem())
this.addDecoderToCache(cacheKey, decoder)
return decoder
}
func (this *Codec) BorrowStream() core.IStream {
stream := this.streamPool.Get().(core.IStream)
return stream
}
func (this *Codec) ReturnStream(stream core.IStream) {
this.streamPool.Put(stream)
}
func (this *Codec) BorrowExtractor(buf []byte) core.IExtractor {
extra := this.extraPool.Get().(core.IExtractor)
extra.ResetBytes(buf)
return extra
}
func (this *Codec) ReturnExtractor(extra core.IExtractor) {
this.extraPool.Put(extra)
}
//编码对象到json
func (this *Codec) MarshalJson(val interface{}, option ...core.ExecuteOption) (buf []byte, err error) {
stream := this.BorrowStream()
defer this.ReturnStream(stream)
stream.WriteVal(val)
if stream.Error() != nil {
return nil, stream.Error()
}
result := stream.Buffer()
copied := make([]byte, len(result))
copy(copied, result)
return copied, nil
}
//解码json到对象
func (this *Codec) UnmarshalJson(data []byte, v interface{}, option ...core.ExecuteOption) error {
extra := this.BorrowExtractor(data)
defer this.ReturnExtractor(extra)
extra.ReadVal(v)
return extra.Error()
}
//编码对象到mapjson
func (this *Codec) MarshalMapJson(val interface{}, option ...core.ExecuteOption) (ret map[string]string, err error) {
if nil == val {
err = errors.New("val is null")
return
}
cacheKey := reflect2.RTypeOf(val)
encoder := this.GetEncoderFromCache(cacheKey)
if encoder == nil {
typ := reflect2.TypeOf(val)
encoder = this.EncoderOf(typ)
}
if encoderMapJson, ok := encoder.(core.IEncoderMapJson); !ok {
err = fmt.Errorf("val type:%T not support MarshalMapJson", val)
} else {
ret, err = encoderMapJson.EncodeToMapJson(reflect2.PtrOf(val))
}
return
}
//解码mapjson到对象
func (this *Codec) UnmarshalMapJson(data map[string]string, val interface{}, option ...core.ExecuteOption) (err error) {
cacheKey := reflect2.RTypeOf(val)
decoder := this.GetDecoderFromCache(cacheKey)
if decoder == nil {
typ := reflect2.TypeOf(val)
if typ == nil || typ.Kind() != reflect.Ptr {
err = errors.New("can only unmarshal into pointer")
return
}
decoder = this.DecoderOf(typ)
}
ptr := reflect2.PtrOf(val)
if ptr == nil {
err = errors.New("can not read into nil pointer")
return
}
if decoderMapJson, ok := decoder.(core.IDecoderMapJson); !ok {
err = fmt.Errorf("val type:%T not support MarshalMapJson", val)
} else {
err = decoderMapJson.DecodeForMapJson(ptr, data)
}
return
}
//编码对象到sliceJson
func (this *Codec) MarshalSliceJson(val interface{}, option ...core.ExecuteOption) (ret []string, err error) {
if nil == val {
err = errors.New("val is null")
return
}
cacheKey := reflect2.RTypeOf(val)
encoder := this.GetEncoderFromCache(cacheKey)
if encoder == nil {
typ := reflect2.TypeOf(val)
encoder = this.EncoderOf(typ)
}
if encoderMapJson, ok := encoder.(core.IEncoderSliceJson); !ok {
err = fmt.Errorf("val type:%T not support MarshalMapJson", val)
} else {
ret, err = encoderMapJson.EncodeToSliceJson(reflect2.PtrOf(val))
}
return
}
//解码sliceJson到对象
func (this *Codec) UnmarshalSliceJson(data []string, val interface{}, option ...core.ExecuteOption) (err error) {
cacheKey := reflect2.RTypeOf(val)
decoder := this.GetDecoderFromCache(cacheKey)
if decoder == nil {
typ := reflect2.TypeOf(val)
if typ == nil || typ.Kind() != reflect.Ptr {
err = errors.New("can only unmarshal into pointer")
return
}
decoder = this.DecoderOf(typ)
}
ptr := reflect2.PtrOf(val)
if ptr == nil {
err = errors.New("can not read into nil pointer")
return
}
if decoderMapJson, ok := decoder.(core.IDecoderSliceJson); !ok {
err = fmt.Errorf("val type:%T not support UnmarshalSliceJson", val)
} else {
err = decoderMapJson.DecodeForSliceJson(ptr, data)
}
return
}
///日志***********************************************************************
func (this *Codec) Debug() bool {
return this.options.Debug
}
func (this *Codec) Debugf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Debugf("[SYS Codec] "+format, a...)
}
}
func (this *Codec) Infof(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Infof("[SYS Codec] "+format, a...)
}
}
func (this *Codec) Warnf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Warnf("[SYS Codec] "+format, a...)
}
}
func (this *Codec) Errorf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Errorf("[SYS Codec] "+format, a...)
}
}
func (this *Codec) Panicf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Panicf("[SYS Codec] "+format, a...)
}
}
func (this *Codec) Fatalf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Fatalf("[SYS Codec] "+format, a...)
}
}

View File

@ -1,56 +0,0 @@
package codec
import (
"go_dreamfactory/lego/sys/codec/core"
"github.com/modern-go/reflect2"
)
type (
ISys interface {
DecoderOf(typ reflect2.Type) core.IDecoder
EncoderOf(typ reflect2.Type) core.IEncoder
MarshalJson(v interface{}, option ...core.ExecuteOption) ([]byte, error)
UnmarshalJson(data []byte, v interface{}, option ...core.ExecuteOption) error
MarshalMapJson(val interface{}, option ...core.ExecuteOption) (ret map[string]string, err error)
UnmarshalMapJson(data map[string]string, val interface{}, option ...core.ExecuteOption) (err error)
MarshalSliceJson(val interface{}, option ...core.ExecuteOption) (ret []string, err error)
UnmarshalSliceJson(data []string, val interface{}, option ...core.ExecuteOption) (err error)
}
)
var defsys ISys
func OnInit(config map[string]interface{}, option ...core.Option) (err error) {
defsys, err = newSys(newOptions(config, option...))
return
}
func NewSys(option ...core.Option) (sys ISys, err error) {
sys, err = newSys(newOptionsByOption(option...))
return
}
func DecoderOf(typ reflect2.Type) core.IDecoder {
return defsys.DecoderOf(typ)
}
func EncoderOf(typ reflect2.Type) core.IEncoder {
return defsys.EncoderOf(typ)
}
func MarshalJson(v interface{}, option ...core.ExecuteOption) ([]byte, error) {
return defsys.MarshalJson(v, option...)
}
func UnmarshalJson(data []byte, v interface{}, option ...core.ExecuteOption) error {
return defsys.UnmarshalJson(data, v, option...)
}
func MarshalMapJson(val interface{}, option ...core.ExecuteOption) (ret map[string]string, err error) {
return defsys.MarshalMapJson(val, option...)
}
func UnmarshalMapJson(data map[string]string, val interface{}, option ...core.ExecuteOption) (err error) {
return defsys.UnmarshalMapJson(data, val, option...)
}
func MarshalSliceJson(val interface{}, option ...core.ExecuteOption) (ret []string, err error) {
return defsys.MarshalSliceJson(val, option...)
}
func UnmarshalSliceJson(data []string, val interface{}, option ...core.ExecuteOption) (err error) {
return defsys.UnmarshalSliceJson(data, val)
}

View File

@ -1,30 +0,0 @@
package core
import (
"go_dreamfactory/lego/sys/log"
)
type Option func(*Options)
type Options struct {
IndentionStep int //缩进步骤
ObjectFieldMustBeSimpleString bool //对象字段必须是简单字符串
OnlyTaggedField bool //仅仅处理标签字段
DisallowUnknownFields bool //禁止未知字段
CaseSensitive bool //是否区分大小写
TagKey string //标签
Debug bool //日志是否开启
Log log.ILog
}
//执行选项
type ExecuteOption func(*ExecuteOptions)
type ExecuteOptions struct {
}
func NewExecuteOptions(opts ...ExecuteOption) ExecuteOptions {
options := ExecuteOptions{}
for _, o := range opts {
o(&options)
}
return options
}

View File

@ -1,38 +0,0 @@
package codec
import (
"go_dreamfactory/lego/sys/codec/core"
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/lego/utils/mapstructure"
)
func newOptions(config map[string]interface{}, opts ...core.Option) core.Options {
options := core.Options{
IndentionStep: 2,
TagKey: "json",
}
if config != nil {
mapstructure.Decode(config, &options)
}
for _, o := range opts {
o(&options)
}
if options.Debug && options.Log == nil {
options.Log = log.Clone()
}
return options
}
func newOptionsByOption(opts ...core.Option) core.Options {
options := core.Options{
IndentionStep: 2,
TagKey: "json",
}
for _, o := range opts {
o(&options)
}
if options.Debug && options.Log == nil {
options.Log = log.Clone()
}
return options
}

View File

@ -1,45 +0,0 @@
package render
import "go_dreamfactory/lego/sys/codec/core"
const maxDepth = 10000
var hexDigits []byte
var valueTypes []core.ValueType
func init() {
hexDigits = make([]byte, 256)
for i := 0; i < len(hexDigits); i++ {
hexDigits[i] = 255
}
for i := '0'; i <= '9'; i++ {
hexDigits[i] = byte(i - '0')
}
for i := 'a'; i <= 'f'; i++ {
hexDigits[i] = byte((i - 'a') + 10)
}
for i := 'A'; i <= 'F'; i++ {
hexDigits[i] = byte((i - 'A') + 10)
}
valueTypes = make([]core.ValueType, 256)
for i := 0; i < len(valueTypes); i++ {
valueTypes[i] = core.InvalidValue
}
valueTypes['"'] = core.StringValue
valueTypes['-'] = core.NumberValue
valueTypes['0'] = core.NumberValue
valueTypes['1'] = core.NumberValue
valueTypes['2'] = core.NumberValue
valueTypes['3'] = core.NumberValue
valueTypes['4'] = core.NumberValue
valueTypes['5'] = core.NumberValue
valueTypes['6'] = core.NumberValue
valueTypes['7'] = core.NumberValue
valueTypes['8'] = core.NumberValue
valueTypes['9'] = core.NumberValue
valueTypes['t'] = core.BoolValue
valueTypes['f'] = core.BoolValue
valueTypes['n'] = core.NilValue
valueTypes['['] = core.ArrayValue
valueTypes['{'] = core.ObjectValue
}

View File

@ -1,206 +0,0 @@
package render
import (
"go_dreamfactory/lego/sys/codec/core"
"go_dreamfactory/lego/sys/codec/utils"
"github.com/modern-go/reflect2"
)
func NewStream(codec core.ICodec, bufSize int) *JsonStream {
return &JsonStream{
codec: codec,
buf: make([]byte, 0, bufSize),
err: nil,
indention: 0,
}
}
type JsonStream struct {
codec core.ICodec
err error
buf []byte
indention int
}
//写入对象
func (this *JsonStream) WriteVal(val interface{}) {
if nil == val {
this.WriteNil()
return
}
cacheKey := reflect2.RTypeOf(val)
encoder := this.codec.GetEncoderFromCache(cacheKey)
if encoder == nil {
typ := reflect2.TypeOf(val)
encoder = this.codec.EncoderOf(typ)
}
encoder.Encode(reflect2.PtrOf(val), this)
}
func (this *JsonStream) WriteNil() {
this.writeFourBytes('n', 'u', 'l', 'l')
}
func (this *JsonStream) WriteEmptyArray() {
this.writeTwoBytes('[', ']')
}
func (this *JsonStream) WriteArrayStart() {
this.indention += this.codec.Options().IndentionStep
this.writeByte('[')
this.writeIndention(0)
}
func (this *JsonStream) WriteArrayEnd() {
this.writeIndention(this.codec.Options().IndentionStep)
this.indention -= this.codec.Options().IndentionStep
this.writeByte(']')
}
func (this *JsonStream) WriteEmptyObject() {
this.writeTwoBytes('{', '}')
}
func (this *JsonStream) WriteObjectStart() {
this.indention += this.codec.Options().IndentionStep
this.writeByte('{')
this.writeIndention(0)
}
func (this *JsonStream) WriteObjectEnd() {
this.writeIndention(this.codec.Options().IndentionStep)
this.indention -= this.codec.Options().IndentionStep
this.writeByte('}')
}
func (this *JsonStream) WriteMemberSplit() {
this.writeByte(',')
this.writeIndention(0)
}
func (this *JsonStream) WriteKVSplit() {
this.writeByte(':')
}
func (this *JsonStream) WriteKeyStart() {
this.writeByte('"')
}
func (this *JsonStream) WriteKeyEnd() {
this.writeByte('"')
}
func (this *JsonStream) WriteObjectFieldName(val string) {
this.WriteString(val)
if this.indention > 0 {
this.writeTwoBytes(':', ' ')
} else {
this.writeByte(':')
}
}
func (this *JsonStream) WriteBool(val bool) {
if val {
this.writeTrue()
} else {
this.writeFalse()
}
}
func (this *JsonStream) WriteInt8(val int8) {
utils.WriteInt8ToString(&this.buf, val)
}
func (this *JsonStream) WriteInt16(val int16) {
utils.WriteInt16ToString(&this.buf, val)
}
func (this *JsonStream) WriteInt32(val int32) {
utils.WriteInt32ToString(&this.buf, val)
}
func (this *JsonStream) WriteInt64(val int64) {
utils.WriteInt64ToString(&this.buf, val)
}
func (this *JsonStream) WriteUint8(val uint8) {
utils.WriteUint8ToString(&this.buf, val)
}
func (this *JsonStream) WriteUint16(val uint16) {
utils.WriteUint16ToString(&this.buf, val)
}
func (this *JsonStream) WriteUint32(val uint32) {
utils.WriteUint32ToString(&this.buf, val)
}
func (this *JsonStream) WriteUint64(val uint64) {
utils.WriteUint64ToString(&this.buf, val)
}
func (this *JsonStream) WriteFloat32(val float32) {
utils.WriteFloat32ToString(&this.buf, val)
}
func (this *JsonStream) WriteFloat64(val float64) {
utils.WriteFloat64ToString(&this.buf, val)
}
func (this *JsonStream) WriteString(val string) {
valLen := len(val)
this.buf = append(this.buf, '"')
i := 0
for ; i < valLen; i++ {
c := val[i]
if c > 31 && c != '"' && c != '\\' {
this.buf = append(this.buf, c)
} else {
break
}
}
if i == valLen {
this.buf = append(this.buf, '"')
return
}
utils.WriteStringSlowPath(&this.buf, i, val, valLen)
}
func (this *JsonStream) WriteBytes(val []byte) {
this.buf = append(this.buf, val...)
}
func (this *JsonStream) Reset(bufSize int) {
this.buf = make([]byte, 0, bufSize)
this.err = nil
this.indention = 0
return
}
func (this *JsonStream) Buffer() []byte {
return this.buf
}
func (this *JsonStream) Error() error {
return this.err
}
func (this *JsonStream) SetErr(err error) {
this.err = err
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------
// WriteTrue write true to stream
func (stream *JsonStream) writeTrue() {
stream.writeFourBytes('t', 'r', 'u', 'e')
}
// WriteFalse write false to stream
func (stream *JsonStream) writeFalse() {
stream.writeFiveBytes('f', 'a', 'l', 's', 'e')
}
func (this *JsonStream) writeByte(c byte) {
this.buf = append(this.buf, c)
}
func (this *JsonStream) writeTwoBytes(c1 byte, c2 byte) {
this.buf = append(this.buf, c1, c2)
}
func (this *JsonStream) writeThreeBytes(c1 byte, c2 byte, c3 byte) {
this.buf = append(this.buf, c1, c2, c3)
}
func (this *JsonStream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) {
this.buf = append(this.buf, c1, c2, c3, c4)
}
func (this *JsonStream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) {
this.buf = append(this.buf, c1, c2, c3, c4, c5)
}
func (stream *JsonStream) writeIndention(delta int) {
if stream.indention == 0 {
return
}
stream.writeByte('\n')
toWrite := stream.indention - delta
for i := 0; i < toWrite; i++ {
stream.buf = append(stream.buf, ' ')
}
}

View File

@ -1,106 +0,0 @@
package codec_test
import (
"fmt"
"reflect"
"testing"
"go_dreamfactory/lego/sys/codec"
"go_dreamfactory/lego/sys/log"
"github.com/modern-go/reflect2"
)
type TestData struct {
Name string
Value int
Array []interface{}
Data map[string]interface{}
}
type Test1Data struct {
Name string
Value int
}
func Test_sys_slice(t *testing.T) {
if err := log.OnInit(nil); err != nil {
fmt.Printf("log init err:%v", err)
return
}
if sys, err := codec.NewSys(); err != nil {
fmt.Printf("gin init err:%v", err)
} else {
data := []*Test1Data{{"liwe", 1}, {"liwe2", 2}}
d, err := sys.MarshalJson(data)
fmt.Printf("codec Marshal d:%s err:%v", d, err)
data = []*Test1Data{}
err = sys.UnmarshalJson(d, &data)
fmt.Printf("codec UnmarshalJson data:%v err:%v", data, err)
}
}
func Test_sys_json(t *testing.T) {
if err := log.OnInit(nil); err != nil {
fmt.Printf("log init err:%v", err)
return
}
if sys, err := codec.NewSys(); err != nil {
fmt.Printf("gin init err:%v", err)
} else {
d, err := sys.MarshalJson(&TestData{Name: "http://liwei1dao.com?asd=1&dd=1", Value: 10, Array: []interface{}{1, "dajiahao", &Test1Data{Name: "liwe1dao", Value: 123}}, Data: map[string]interface{}{"hah": 1, "asd": 999}})
fmt.Printf("codec Marshal d:%s err:%v", d, err)
data := &TestData{}
err = sys.UnmarshalJson(d, data)
fmt.Printf("codec UnmarshalJson data:%v err:%v", data, err)
}
}
func Test_sys_mapjson(t *testing.T) {
if err := log.OnInit(nil); err != nil {
fmt.Printf("log init err:%v", err)
return
}
if sys, err := codec.NewSys(); err != nil {
fmt.Printf("gin init err:%v", err)
} else {
m := map[string]interface{}{"liwe": 123, "aasd": "123"}
fmt.Printf("codec Marshal m:%s err:%v", m, err)
d, err := sys.MarshalMapJson(&TestData{Name: "http://liwei1dao.com?asd=1&dd=1", Value: 10, Array: []interface{}{1, "dajiahao", &Test1Data{Name: "liwe1dao", Value: 123}}, Data: map[string]interface{}{"hah": 1, "asd": 999}})
fmt.Printf("codec Marshal d:%s err:%v", d, err)
data := &TestData{}
err = sys.UnmarshalMapJson(d, data)
fmt.Printf("codec UnmarshalJson data:%v err:%v", data, err)
}
}
func Test_sys_reflect2(t *testing.T) {
data := []*Test1Data{}
ptr := reflect2.TypeOf(&data)
kind := ptr.Kind()
switch kind {
case reflect.Interface:
return
case reflect.Struct:
return
case reflect.Array:
return
case reflect.Slice:
return
case reflect.Map:
return
case reflect.Ptr:
ptrType := ptr.(*reflect2.UnsafePtrType)
elemType := ptrType.Elem()
kind = elemType.Kind()
if kind == reflect.Slice {
sliceelem := elemType.(*reflect2.UnsafeSliceType).Elem()
sliceelemkind := sliceelem.Kind()
if sliceelemkind == reflect.Ptr {
return
}
return
}
return
default:
return
}
}

View File

@ -18,13 +18,21 @@ type ISys interface {
var defsys ISys
func OnInit(config map[string]interface{}, option ...Option) (err error) {
defsys, err = newSys(newOptions(config, option...))
func OnInit(config map[string]interface{}, opt ...Option) (err error) {
var option *Options
if option, err = newOptions(config, opt...); err != nil {
return
}
defsys, err = newSys(option)
return
}
func NewSys(option ...Option) (sys ISys, err error) {
sys, err = newSys(newOptionsByOption(option...))
func NewSys(opt ...Option) (sys ISys, err error) {
var option *Options
if option, err = newOptionsByOption(opt...); err != nil {
return
}
sys, err = newSys(option)
return
}

View File

@ -16,6 +16,7 @@ import (
"go_dreamfactory/lego/sys/gin/binding"
"go_dreamfactory/lego/sys/gin/render"
"go_dreamfactory/lego/sys/log"
)
const (
@ -30,17 +31,17 @@ const (
)
const abortIndex int8 = math.MaxInt8 >> 1
func newContext(sys ISys, engine *Engine, params *Params, skippedNodes *[]skippedNode) *Context {
func newContext(log log.ILogger, engine *Engine, params *Params, skippedNodes *[]skippedNode) *Context {
return &Context{
engine: engine,
params: params,
skippedNodes: skippedNodes,
writermem: ResponseWriter{log: sys},
writermem: ResponseWriter{log: log},
}
}
type Context struct {
Sys ISys
Log log.ILogger
engine *Engine
writermem ResponseWriter
Request *http.Request
@ -351,7 +352,7 @@ func (this *Context) initFormCache() {
req := this.Request
if err := req.ParseMultipartForm(this.engine.MaxMultipartMemory); err != nil {
if !errors.Is(err, http.ErrNotMultipart) {
this.Sys.Errorf("error on parse multipart form array: %v", err)
this.Log.Errorf("error on parse multipart form array: %v", err)
}
}
this.formCache = req.PostForm

View File

@ -2,8 +2,6 @@ package engine
import (
"net/http"
"go_dreamfactory/lego/sys/log"
)
type HandlerFunc func(*Context)
@ -25,11 +23,6 @@ type RouteInfo struct {
type RoutesInfo []RouteInfo
type ISys interface {
log.Ilogf
Debug() bool
}
type IRoutes interface {
Group(relativePath string, handlers ...HandlerFunc) IRoutes
Use(...HandlerFunc) IRoutes

View File

@ -9,6 +9,7 @@ import (
"sync"
"go_dreamfactory/lego/sys/gin/render"
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/lego/utils/codec"
"golang.org/x/net/http2"
@ -33,14 +34,14 @@ var defaultTrustedCIDRs = []*net.IPNet{
},
}
func NewEngine(sys ISys) (engine *Engine) {
func NewEngine(log log.ILogger) (engine *Engine) {
engine = &Engine{
RouterGroup: RouterGroup{
Handlers: nil,
basePath: "/",
root: true,
},
sys: sys,
log: log,
FuncMap: template.FuncMap{},
RedirectTrailingSlash: true,
RedirectFixedPath: false,
@ -72,7 +73,7 @@ var mimePlain = []string{MIMEPlain}
type Engine struct {
RouterGroup
sys ISys
log log.ILogger
UseRawPath bool
/*
如果启用路由器尝试修复当前请求路径如果没有
@ -194,7 +195,7 @@ func (this *Engine) LoadHTMLGlob(pattern string) {
right := this.delims.Right
templ := template.Must(template.New("").Delims(left, right).Funcs(this.FuncMap).ParseGlob(pattern))
if this.sys.Debug() {
if this.log.Enabled(log.DebugLevel) {
this.debugPrintLoadTemplate(templ)
this.HTMLRender = render.HTMLDebug{Glob: pattern, FuncMap: this.FuncMap, Delims: this.delims}
return
@ -208,7 +209,7 @@ LoadHTMLFiles 加载一段 HTML 文件
并将结果与 HTML 渲染器相关联
*/
func (this *Engine) LoadHTMLFiles(files ...string) {
if this.sys.Debug() {
if this.log.Enabled(log.DebugLevel) {
this.HTMLRender = render.HTMLDebug{Files: files, FuncMap: this.FuncMap, Delims: this.delims}
return
}
@ -218,7 +219,7 @@ func (this *Engine) LoadHTMLFiles(files ...string) {
func (this *Engine) SetHTMLTemplate(templ *template.Template) {
if len(this.trees) > 0 {
this.sys.Warnf(`Since SetHTMLTemplate() is NOT thread-safe. It should only be called
this.log.Warnf(`Since SetHTMLTemplate() is NOT thread-safe. It should only be called
at initialization. ie. before any route is registered or the router is listening in a socket:
router := gin.Default()
router.SetHTMLTemplate(template) // << good place
@ -270,10 +271,10 @@ func (this *Engine) addRoute(method, path string, handlers HandlersChain) {
assert1(path[0] == '/', "path must begin with '/'")
assert1(method != "", "HTTP method can not be empty")
assert1(len(handlers) > 0, "there must be at least one handler")
if this.sys.Debug() {
if this.log.Enabled(log.DebugLevel) {
nuHandlers := len(handlers)
handlerName := nameOfFunction(handlers.Last())
this.sys.Debugf("%s:%s --> %s handlers:%d", method, path, handlerName, nuHandlers)
this.log.Debugf("%s:%s --> %s handlers:%d", method, path, handlerName, nuHandlers)
}
root := this.trees.get(method)
if root == nil {
@ -406,7 +407,7 @@ func (this *Engine) serveError(c *Context, code int, defaultMessage []byte) {
c.writermem.Header()["Content-Type"] = mimePlain
_, err := c.Writer.Write(defaultMessage)
if err != nil {
this.sys.Errorf("[SYS-Gin] cannot write message to writer during serve error: %v", err)
this.log.Errorf("[SYS-Gin] cannot write message to writer during serve error: %v", err)
}
return
}
@ -447,7 +448,7 @@ func (this *Engine) redirectRequest(c *Context) {
if req.Method != http.MethodGet {
code = http.StatusTemporaryRedirect
}
this.sys.Debugf("redirecting request %d: %s --> %s", code, rPath, rURL)
this.log.Debugf("redirecting request %d: %s --> %s", code, rPath, rURL)
http.Redirect(c.Writer, req, rURL, code)
c.writermem.WriteHeaderNow()
}
@ -490,12 +491,11 @@ func (this *Engine) prepareTrustedCIDRs() ([]*net.IPNet, error) {
func (this *Engine) allocateContext() *Context {
v := make(Params, 0, this.maxParams)
skippedNodes := make([]skippedNode, 0, this.maxSections)
return &Context{Sys: this.sys, engine: this, params: &v, skippedNodes: &skippedNodes}
return &Context{Log: this.log, engine: this, params: &v, skippedNodes: &skippedNodes}
}
//日志接口-------------------------------------------------------------
func (this *Engine) debugPrintLoadTemplate(tmpl *template.Template) {
if this.sys.Debug() {
var buf strings.Builder
for _, tmpl := range tmpl.Templates() {
buf.WriteString("\t- ")
@ -506,6 +506,6 @@ func (this *Engine) debugPrintLoadTemplate(tmpl *template.Template) {
if !strings.HasSuffix(format, "\n") {
format += "\n"
}
this.sys.Debugf(format, len(tmpl.Templates()), buf.String())
}
this.log.Debugf(format, len(tmpl.Templates()), buf.String())
}

View File

@ -33,7 +33,7 @@ type IResponseWriter interface {
}
type ResponseWriter struct {
http.ResponseWriter
log log.Ilogf
log log.ILogger
size int
status int
}

View File

@ -12,11 +12,11 @@ import (
"go_dreamfactory/lego/sys/gin/middleware/recovery"
)
func newSys(options Options) (sys *Gin, err error) {
func newSys(options *Options) (sys *Gin, err error) {
sys = &Gin{
options: options,
}
sys.engine = engine.NewEngine(sys)
sys.engine = engine.NewEngine(options.Log)
///添加基础中间件
sys.engine.Use(logger.Logger([]string{}), recovery.Recovery())
if options.CertFile != "" && options.KeyFile != "" {
@ -28,7 +28,7 @@ func newSys(options Options) (sys *Gin, err error) {
}
type Gin struct {
options Options
options *Options
server *http.Server
engine *engine.Engine
}
@ -36,7 +36,7 @@ type Gin struct {
func (this *Gin) Run(listenPort int) (err error) {
defer func() {
if err != nil {
this.Errorf("Run err:%v", err)
this.options.Log.Errorf("Run err:%v", err)
}
}()
// if this.engine.IsUnsafeTrustedProxies() {
@ -44,14 +44,14 @@ func (this *Gin) Run(listenPort int) (err error) {
// "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.")
// }
this.Debugf("Listening and serving HTTP on:%d", listenPort)
this.options.Log.Debugf("Listening and serving HTTP on:%d", listenPort)
this.server = &http.Server{
Addr: fmt.Sprintf(":%d", listenPort),
Handler: this.engine.Handler(),
}
go func() {
if err := this.server.ListenAndServe(); err != nil && errors.Is(err, http.ErrServerClosed) {
this.Errorf("Run err:%v", err)
this.options.Log.Errorln(err)
}
}()
// err = http.ListenAndServe(fmt.Sprintf(":%d", this.options.ListenPort), this.Handler())
@ -59,10 +59,10 @@ func (this *Gin) Run(listenPort int) (err error) {
}
func (this *Gin) RunTLS(listenPort int, certFile, keyFile string) (err error) {
this.Debugf("Listening and serving HTTPS on :%d", listenPort)
this.options.Log.Debugf("Listening and serving HTTPS on :%d", listenPort)
defer func() {
if err != nil {
this.Errorf("RunTLS err:%v", err)
this.options.Log.Errorln(err)
}
}()
@ -76,7 +76,7 @@ func (this *Gin) RunTLS(listenPort int, certFile, keyFile string) (err error) {
}
go func() {
if err := this.server.ListenAndServeTLS(certFile, keyFile); err != nil && errors.Is(err, http.ErrServerClosed) {
this.Errorf("listen err:%s", err)
this.options.Log.Errorln(err)
}
}()
// err = http.ListenAndServeTLS(addr, certFile, keyFile, this.Handler())
@ -84,10 +84,10 @@ func (this *Gin) RunTLS(listenPort int, certFile, keyFile string) (err error) {
}
func (this *Gin) RunListener(listener net.Listener) (err error) {
this.Debugf("Listening and serving HTTP on listener what's bind with address@%s", listener.Addr())
this.options.Log.Debugf("Listening and serving HTTP on listener what's bind with address@%s", listener.Addr())
defer func() {
if err != nil {
this.Errorf("Run err:%v", err)
this.options.Log.Errorln(err)
}
}()
@ -102,7 +102,7 @@ func (this *Gin) RunListener(listener net.Listener) (err error) {
func (this *Gin) Close() (err error) {
if err = this.server.Shutdown(context.Background()); err != nil {
this.Errorf("Close err:%v", err)
this.options.Log.Errorln(err)
}
this.server.Close()
return
@ -154,39 +154,3 @@ func (this *Gin) Static(relativePath string, root string) engine.IRoutes {
func (this *Gin) StaticFS(relativePath string, fs http.FileSystem) engine.IRoutes {
return this.engine.StaticFS(relativePath, fs)
}
///日志***********************************************************************
func (this *Gin) Debug() bool {
return this.options.Debug
}
func (this *Gin) Debugf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Debugf("[SYS Gin] "+format, a...)
}
}
func (this *Gin) Infof(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Infof("[SYS Gin] "+format, a...)
}
}
func (this *Gin) Warnf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Warnf("[SYS Gin] "+format, a...)
}
}
func (this *Gin) Errorf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Errorf("[SYS Gin] "+format, a...)
}
}
func (this *Gin) Panicf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Panicf("[SYS Gin] "+format, a...)
}
}
func (this *Gin) Fatalf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Fatalf("[SYS Gin] "+format, a...)
}
}

View File

@ -71,7 +71,7 @@ func Logger(SkipPaths []string) engine.HandlerFunc {
path = path + "?" + raw
}
param.Path = path
c.Sys.Debugf(fmt.Sprintf("[FORMATTER TEST] %v | %3d | %13v | %15s | %-7s %s\n%s",
c.Log.Debugf(fmt.Sprintf("[FORMATTER TEST] %v | %3d | %13v | %15s | %-7s %s\n%s",
param.TimeStamp.Format("2006/01/02 - 15:04:05"),
param.StatusCode,
param.Latency,

View File

@ -73,13 +73,10 @@ func CustomRecoveryWithWriter(handle RecoveryFunc) engine.HandlerFunc {
}
headersToStr := strings.Join(headers, "\r\n")
if brokenPipe {
c.Sys.Errorf("%s\n%s%s", err, headersToStr, reset)
} else if c.Sys.Debug() {
c.Sys.Errorf("[Recovery] %s panic recovered:\n%s\n%s\n%s%s",
timeFormat(time.Now()), headersToStr, err, stack, reset)
c.Log.Errorf("%s\n%s%s", err, headersToStr, reset)
} else {
c.Sys.Errorf("[Recovery] %s panic recovered:\n%s\n%s%s",
timeFormat(time.Now()), err, stack, reset)
c.Log.Errorf("[Recovery] %s panic recovered:\n%s\n%s\n%s%s",
timeFormat(time.Now()), headersToStr, err, stack, reset)
}
if brokenPipe {

View File

@ -1,6 +1,8 @@
package gin
import (
"errors"
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/lego/utils/mapstructure"
)
@ -11,7 +13,7 @@ type Options struct {
CertFile string //tls文件
KeyFile string //tls文件
Debug bool //日志是否开启
Log log.ILog
Log log.ILogger
}
func SetListenPort(v int) Option {
@ -38,39 +40,47 @@ func SetDebug(v bool) Option {
}
}
func SetLog(v log.ILog) Option {
func SetLog(v log.ILogger) Option {
return func(o *Options) {
o.Log = v
}
}
func newOptions(config map[string]interface{}, opts ...Option) Options {
options := Options{
func newOptions(config map[string]interface{}, opts ...Option) (options *Options, err error) {
options = &Options{
ListenPort: 8080,
CertFile: "",
KeyFile: "",
Debug: true,
Log: log.Clone(log.SetLoglayer(2)),
}
if config != nil {
mapstructure.Decode(config, &options)
}
for _, o := range opts {
o(&options)
o(options)
}
return options
if options.Log = log.NewTurnlog(options.Debug, log.Clone("sys.discovery", 2)); options.Log == nil {
err = errors.New("log is nil")
}
return
}
func newOptionsByOption(opts ...Option) Options {
options := Options{
func newOptionsByOption(opts ...Option) (options *Options, err error) {
options = &Options{
ListenPort: 8080,
CertFile: "",
KeyFile: "",
Debug: true,
Log: log.Clone(log.SetLoglayer(2)),
}
for _, o := range opts {
o(&options)
o(options)
}
return options
if options.Log = log.NewTurnlog(options.Debug, log.Clone("sys.discovery", 2)); options.Log == nil {
err = errors.New("log is nil")
}
return
}

View File

@ -14,7 +14,7 @@ import (
)
func Test_sys(t *testing.T) {
if err := log.OnInit(nil); err != nil {
if err := log.OnInit(nil, log.SetFileName("test"), log.SetReportCaller(true)); err != nil {
fmt.Printf("log init err:%v", err)
return
}

12
lego/sys/log/chown.go Normal file
View File

@ -0,0 +1,12 @@
//go:build !linux
// +build !linux
package log
import (
"os"
)
func chown(_ string, _ os.FileInfo) error {
return nil
}

View File

@ -0,0 +1,19 @@
package log
import (
"os"
"syscall"
)
// osChown is a var so we can mock it out during tests.
var osChown = os.Chown
func chown(name string, info os.FileInfo) error {
f, err := os.OpenFile(name, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, info.Mode())
if err != nil {
return err
}
f.Close()
stat := info.Sys().(*syscall.Stat_t)
return osChown(name, int(stat.Uid), int(stat.Gid))
}

View File

@ -1,82 +1,138 @@
package log
import (
"fmt"
"os"
"strings"
"go_dreamfactory/lego/utils/flietools"
)
var AllLevels = []Loglevel{
PanicLevel,
FatalLevel,
ErrorLevel,
WarnLevel,
InfoLevel,
DebugLevel,
}
type (
LogStrut interface {
ToString() (str string)
}
Field struct {
Key string
Value interface{}
}
Fields []Field
Ilogf interface {
Debugf(format string, a ...interface{})
Infof(format string, a ...interface{})
Warnf(format string, a ...interface{})
Errorf(format string, a ...interface{})
Panicf(format string, a ...interface{})
Fatalf(format string, a ...interface{})
Debugf(format string, args ...interface{})
Infof(format string, args ...interface{})
Printf(format string, args ...interface{})
Warnf(format string, args ...interface{})
Errorf(format string, args ...interface{})
Fatalf(format string, args ...interface{})
Panicf(format string, args ...interface{})
}
IlogIn interface {
Debugln(args ...interface{})
Infoln(args ...interface{})
Println(args ...interface{})
Warnln(args ...interface{})
Errorln(args ...interface{})
Fatalln(args ...interface{})
Panicln(args ...interface{})
}
ILog interface {
Clone(option ...Option) ILog
Debug(msg string, fields ...Field)
Info(msg string, fields ...Field)
Warn(msg string, fields ...Field)
Error(msg string, fields ...Field)
Panic(msg string, fields ...Field)
Fatal(msg string, fields ...Field)
Debug(msg string, args ...Field)
Info(msg string, args ...Field)
Print(msg string, args ...Field)
Warn(msg string, args ...Field)
Error(msg string, args ...Field)
Fatal(msg string, args ...Field)
Panic(msg string, args ...Field)
}
ILogger interface {
SetName(name string)
Enabled(lvl Loglevel) bool
Ilogf
IlogIn
ILog
}
ISys interface {
Clone(name string, skip int) ILogger
ILogger
}
)
var (
defsys ILog
defsys ISys
)
func OnInit(config map[string]interface{}, option ...Option) (err error) {
defsys, err = newSys(newOptions(config, option...))
func OnInit(config map[string]interface{}, opt ...Option) (err error) {
var option *Options
if option, err = newOptions(config, opt...); err != nil {
return
}
func NewSys(option ...Option) (sys ILog, err error) {
sys, err = newSys(newOptionsByOption(option...))
}
defsys, err = newSys(option)
return
}
func Clone(option ...Option) ILog {
if defsys != nil {
return defsys.Clone(option...)
func NewSys(opt ...Option) (sys ISys, err error) {
var option *Options
if option, err = newOptionsByOption(opt...); err != nil {
return
}
return nil
sys, err = newSys(option)
return
}
func Debug(msg string, fields ...Field) { defsys.Debug(msg, fields...) }
func Info(msg string, fields ...Field) { defsys.Info(msg, fields...) }
func Warn(msg string, fields ...Field) { defsys.Warn(msg, fields...) }
func Error(msg string, fields ...Field) { defsys.Error(msg, fields...) }
func Panic(msg string, fields ...Field) { defsys.Panic(msg, fields...) }
func Fatal(msg string, fields ...Field) { defsys.Fatal(msg, fields...) }
func Debugf(format string, a ...interface{}) { defsys.Debugf(format, a...) }
func Infof(format string, a ...interface{}) { defsys.Infof(format, a...) }
func Warnf(format string, a ...interface{}) { defsys.Warnf(format, a...) }
func Errorf(format string, a ...interface{}) { defsys.Errorf(format, a...) }
func Panicf(format string, a ...interface{}) { defsys.Panicf(format, a...) }
func Fatalf(format string, a ...interface{}) { defsys.Fatalf(format, a...) }
//创建日志文件
func createlogfile(logpath string) error {
logdir := string(logpath[0:strings.LastIndex(logpath, "/")])
if !flietools.IsExist(logdir) {
err := os.MkdirAll(logdir, os.ModePerm)
if err != nil {
return fmt.Errorf("创建日志路径失败 1" + err.Error())
}
}
return nil
func Clone(name string, skip int) ILogger {
return defsys.Clone(name, skip)
}
func Debug(msg string, args ...Field) {
defsys.Debug(msg, args...)
}
func Info(msg string, args ...Field) {
defsys.Info(msg, args...)
}
func Warn(msg string, args ...Field) {
defsys.Warn(msg, args...)
}
func Error(msg string, args ...Field) {
defsys.Error(msg, args...)
}
func Fatal(msg string, args ...Field) {
defsys.Fatal(msg, args...)
}
func Panic(msg string, args ...Field) {
defsys.Panic(msg, args...)
}
func Debugf(format string, args ...interface{}) {
defsys.Debugf(format, args...)
}
func Infof(format string, args ...interface{}) {
defsys.Infof(format, args...)
}
func Warnf(format string, args ...interface{}) {
defsys.Warnf(format, args...)
}
func Errorf(format string, args ...interface{}) {
defsys.Errorf(format, args...)
}
func Fatalf(format string, args ...interface{}) {
defsys.Fatalf(format, args...)
}
func Panicf(format string, args ...interface{}) {
defsys.Panicf(format, args...)
}
func Debugln(args ...interface{}) {
defsys.Debugln(args...)
}
func Infoln(args ...interface{}) {
defsys.Infoln(args...)
}
func Println(args ...interface{}) {
defsys.Println(args...)
}
func Warnln(args ...interface{}) {
defsys.Warnln(args...)
}
func Errorln(args ...interface{}) {
defsys.Errorln(args...)
}
func Fatalln(args ...interface{}) {
defsys.Fatalln(args...)
}
func Panicln(args ...interface{}) {
defsys.Panicln(args...)
}

116
lego/sys/log/entry.go Normal file
View File

@ -0,0 +1,116 @@
package log
import (
"fmt"
"reflect"
"strings"
"sync"
"time"
"go_dreamfactory/lego/utils/pools"
)
var (
_cePool = sync.Pool{New: func() interface{} {
// Pre-allocate some space for cores.
return &Entry{
Data: make(Fields, 0, 6),
}
}}
)
func getEntry() *Entry {
return _cePool.Get().(*Entry)
}
func putEntry(e *Entry) {
e.reset()
_cePool.Put(e)
}
//日志堆栈信息
type EntryCaller struct {
Defined bool
PC uintptr
File string
Line int
Function string
Stack string
}
func (ec EntryCaller) String() string {
return ec.FullPath()
}
func (ec EntryCaller) FullPath() string {
if !ec.Defined {
return "undefined"
}
buf := pools.BufferPoolGet()
buf.AppendString(ec.File)
buf.AppendByte(':')
buf.AppendInt(int64(ec.Line))
caller := buf.String()
buf.Free()
return caller
}
func (ec EntryCaller) TrimmedPath() string {
if !ec.Defined {
return "undefined"
}
idx := strings.LastIndexByte(ec.File, '/')
if idx == -1 {
return ec.FullPath()
}
idx = strings.LastIndexByte(ec.File[:idx], '/')
if idx == -1 {
return ec.FullPath()
}
buf := pools.BufferPoolGet()
buf.AppendString(ec.File[idx+1:])
buf.AppendByte(':')
buf.AppendInt(int64(ec.Line))
caller := buf.String()
buf.Free()
return caller
}
type Entry struct {
Name string
Level Loglevel
Caller EntryCaller
Time time.Time
Message string
Data Fields
Err string
}
func (entry *Entry) reset() {
entry.Message = ""
entry.Err = ""
entry.Data = entry.Data[:0]
}
func (entry *Entry) WithFields(fields ...Field) {
if cap(entry.Data) < len(fields) {
entry.Data = make(Fields, 0, cap(entry.Data)+len(fields))
}
fieldErr := entry.Err
for _, v := range fields {
isErrField := false
if t := reflect.TypeOf(v.Value); t != nil {
switch {
case t.Kind() == reflect.Func, t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Func:
isErrField = true
}
}
if isErrField {
tmp := fmt.Sprintf("can not add field %q", v.Key)
if fieldErr != "" {
fieldErr = entry.Err + ", " + tmp
} else {
fieldErr = tmp
}
} else {
entry.Data = append(entry.Data, v)
}
}
}

391
lego/sys/log/flieout.go Normal file
View File

@ -0,0 +1,391 @@
package log
import (
"compress/gzip"
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"sort"
"strings"
"sync"
"time"
)
const (
backupTimeFormat = "2006-01-02T15-04-05.000"
compressSuffix = ".gz"
defaultMaxSize = 100
)
var (
currentTime = time.Now
osStat = os.Stat
megabyte = 1024 * 1024
)
//日志文件输出
type LogFileOut struct {
Filename string `json:"filename" yaml:"filename"` //日志文件名称
MaxSize int `json:"maxsize" yaml:"maxsize"` //日志文件的大小
CupTime time.Duration `json:"cuptime" yaml:"cuptime"` //日志切割间隔时间
MaxAge int `json:"maxage" yaml:"maxage"` //日志的最大备份天数
MaxBackups int `json:"maxbackups" yaml:"maxbackups"` //备份日志的最大数量
LocalTime bool `json:"localtime" yaml:"localtime"` //是使用本地时间还是使用世界标准时间
Compress bool `json:"compress" yaml:"compress"` //是否压缩备份日志
size int64
ctime time.Time
file *os.File
mu sync.Mutex
millCh chan bool
startMill sync.Once
}
func (l *LogFileOut) filename() string {
if l.Filename != "" {
return l.Filename
}
name := filepath.Base(os.Args[0]) + "-lumberjack.log"
return filepath.Join(os.TempDir(), name)
}
func (l *LogFileOut) dir() string {
return filepath.Dir(l.filename())
}
func (l *LogFileOut) max() int64 {
if l.MaxSize == 0 {
return int64(defaultMaxSize * megabyte)
}
return int64(l.MaxSize) * int64(megabyte)
}
func (l *LogFileOut) Write(p []byte) (n int, err error) {
l.mu.Lock()
defer l.mu.Unlock()
writeLen := int64(len(p))
if writeLen > l.max() {
return 0, fmt.Errorf(
"write length %d exceeds maximum file size %d", writeLen, l.max(),
)
}
if l.file == nil {
if err = l.openExistingOrNew(len(p)); err != nil {
return 0, err
}
}
n, err = l.file.Write(p)
l.size += int64(n)
return n, err
}
func (l *LogFileOut) openExistingOrNew(writeLen int) error {
l.mill()
filename := l.filename()
info, err := osStat(filename)
if os.IsNotExist(err) {
return l.openNew()
}
if err != nil {
return fmt.Errorf("error getting log file info: %s", err)
}
//校验是否需要切割日志
if info.Size()+int64(writeLen) >= l.max() || time.Since(l.ctime) > l.CupTime {
return l.rotate()
}
file, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
// if we fail to open the old log file for some reason, just ignore
// it and open a new log file.
return l.openNew()
}
l.file = file
l.size = info.Size()
return nil
}
//日志切割
func (l *LogFileOut) rotate() error {
if err := l.close(); err != nil {
return err
}
if err := l.openNew(); err != nil {
return err
}
l.mill()
return nil
}
func (l *LogFileOut) millRunOnce() error {
if l.MaxBackups == 0 && l.MaxAge == 0 && !l.Compress {
return nil
}
files, err := l.oldLogFiles()
if err != nil {
return err
}
var compress, remove []logInfo
if l.MaxBackups > 0 && l.MaxBackups < len(files) {
preserved := make(map[string]bool)
var remaining []logInfo
for _, f := range files {
// Only count the uncompressed log file or the
// compressed log file, not both.
fn := f.Name()
if strings.HasSuffix(fn, compressSuffix) {
fn = fn[:len(fn)-len(compressSuffix)]
}
preserved[fn] = true
if len(preserved) > l.MaxBackups {
remove = append(remove, f)
} else {
remaining = append(remaining, f)
}
}
files = remaining
}
if l.MaxAge > 0 {
diff := time.Duration(int64(24*time.Hour) * int64(l.MaxAge))
cutoff := currentTime().Add(-1 * diff)
var remaining []logInfo
for _, f := range files {
if f.timestamp.Before(cutoff) {
remove = append(remove, f)
} else {
remaining = append(remaining, f)
}
}
files = remaining
}
if l.Compress {
for _, f := range files {
if !strings.HasSuffix(f.Name(), compressSuffix) {
compress = append(compress, f)
}
}
}
for _, f := range remove {
errRemove := os.Remove(filepath.Join(l.dir(), f.Name()))
if err == nil && errRemove != nil {
err = errRemove
}
}
for _, f := range compress {
fn := filepath.Join(l.dir(), f.Name())
errCompress := compressLogFile(fn, fn+compressSuffix)
if err == nil && errCompress != nil {
err = errCompress
}
}
return err
}
func (l *LogFileOut) millRun() {
for range l.millCh {
// what am I going to do, log this?
_ = l.millRunOnce()
}
}
//触发日志备份管理
func (l *LogFileOut) mill() {
l.startMill.Do(func() {
l.millCh = make(chan bool, 1)
go l.millRun()
})
select {
case l.millCh <- true:
default:
}
}
//备份老的日志文件创建新的日志文件
func (l *LogFileOut) openNew() error {
err := os.MkdirAll(l.dir(), 0755)
if err != nil {
return fmt.Errorf("can't make directories for new logfile: %s", err)
}
name := l.filename()
mode := os.FileMode(0600)
info, err := osStat(name)
//备份老的日志文件
if err == nil {
// Copy the mode off the old logfile.
mode = info.Mode()
// move the existing file
newname := backupName(name, l.LocalTime)
if err := os.Rename(name, newname); err != nil {
return fmt.Errorf("can't rename log file: %s", err)
}
// this is a no-op anywhere but linux
if err := chown(name, info); err != nil {
return err
}
}
//创建新的日志文件
f, err := os.OpenFile(name, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, mode)
if err != nil {
return fmt.Errorf("can't open new logfile: %s", err)
}
l.file = f
l.size = 0
l.ctime = currentTime()
return nil
}
//关闭当前日志文件
func (l *LogFileOut) close() error {
if l.file == nil {
return nil
}
err := l.file.Close()
l.file = nil
return err
}
//获取备份的日子文件集合
func (l *LogFileOut) oldLogFiles() ([]logInfo, error) {
files, err := ioutil.ReadDir(l.dir())
if err != nil {
return nil, fmt.Errorf("can't read log file directory: %s", err)
}
logFiles := []logInfo{}
prefix, ext := l.prefixAndExt()
for _, f := range files {
if f.IsDir() {
continue
}
if t, err := l.timeFromName(f.Name(), prefix, ext); err == nil {
logFiles = append(logFiles, logInfo{t, f})
continue
}
if t, err := l.timeFromName(f.Name(), prefix, ext+compressSuffix); err == nil {
logFiles = append(logFiles, logInfo{t, f})
continue
}
// error parsing means that the suffix at the end was not generated
// by lumberjack, and therefore it's not a backup file.
}
sort.Sort(byFormatTime(logFiles))
return logFiles, nil
}
func (l *LogFileOut) prefixAndExt() (prefix, ext string) {
filename := filepath.Base(l.filename())
ext = filepath.Ext(filename)
prefix = filename[:len(filename)-len(ext)] + "-"
return prefix, ext
}
func (l *LogFileOut) timeFromName(filename, prefix, ext string) (time.Time, error) {
if !strings.HasPrefix(filename, prefix) {
return time.Time{}, errors.New("mismatched prefix")
}
if !strings.HasSuffix(filename, ext) {
return time.Time{}, errors.New("mismatched extension")
}
ts := filename[len(prefix) : len(filename)-len(ext)]
return time.Parse(backupTimeFormat, ts)
}
//日志备份名
func backupName(name string, local bool) string {
dir := filepath.Dir(name)
filename := filepath.Base(name)
ext := filepath.Ext(filename)
prefix := filename[:len(filename)-len(ext)]
t := currentTime()
if !local {
t = t.UTC()
}
timestamp := t.Format(backupTimeFormat)
return filepath.Join(dir, fmt.Sprintf("%s-%s%s", prefix, timestamp, ext))
}
//压缩日志文件
func compressLogFile(src, dst string) (err error) {
f, err := os.Open(src)
if err != nil {
return fmt.Errorf("failed to open log file: %v", err)
}
defer f.Close()
fi, err := osStat(src)
if err != nil {
return fmt.Errorf("failed to stat log file: %v", err)
}
if err := chown(dst, fi); err != nil {
return fmt.Errorf("failed to chown compressed log file: %v", err)
}
// If this file already exists, we presume it was created by
// a previous attempt to compress the log file.
gzf, err := os.OpenFile(dst, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, fi.Mode())
if err != nil {
return fmt.Errorf("failed to open compressed log file: %v", err)
}
defer gzf.Close()
gz := gzip.NewWriter(gzf)
defer func() {
if err != nil {
os.Remove(dst)
err = fmt.Errorf("failed to compress log file: %v", err)
}
}()
if _, err := io.Copy(gz, f); err != nil {
return err
}
if err := gz.Close(); err != nil {
return err
}
if err := gzf.Close(); err != nil {
return err
}
if err := f.Close(); err != nil {
return err
}
if err := os.Remove(src); err != nil {
return err
}
return nil
}
type logInfo struct {
timestamp time.Time
os.FileInfo
}
type byFormatTime []logInfo
func (b byFormatTime) Less(i, j int) bool {
return b[i].timestamp.After(b[j].timestamp)
}
func (b byFormatTime) Swap(i, j int) {
b[i], b[j] = b[j], b[i]
}
func (b byFormatTime) Len() int {
return len(b)
}

70
lego/sys/log/formatter.go Normal file
View File

@ -0,0 +1,70 @@
package log
import (
"sync"
"time"
"go_dreamfactory/lego/utils/pools"
)
var _fieldsPool = sync.Pool{
New: func() interface{} {
return make(Fields, 0, 6)
},
}
func getFields() Fields {
return _fieldsPool.Get().(Fields)
}
func putFields(fields Fields) {
fields = fields[:0]
_fieldsPool.Put(fields)
}
func NewDefEncoderConfig() *EncoderConfig {
return &EncoderConfig{
TimeKey: "ts",
LevelKey: "level",
CallerKey: "caller",
MessageKey: "msg",
StacktraceKey: "stacktrace",
ConsoleSeparator: "\t",
EncodeTime: DefTimeEncoder,
EncodeLevel: LowercaseLevelEncoder,
EncodeCaller: ShortCallerEncoder,
}
}
type TimeEncoder func(time.Time) string
type LevelEncoder func(Loglevel) string
type CallerEncoder func(EntryCaller) string
func DefTimeEncoder(t time.Time) string {
return t.Format("2006/01/02 15:04:05.000")
}
func LowercaseLevelEncoder(l Loglevel) string {
return l.CapitalString()
}
func ShortCallerEncoder(caller EntryCaller) string {
return caller.TrimmedPath()
}
type EncoderConfig struct {
MessageKey string `json:"messageKey" yaml:"messageKey"`
LevelKey string `json:"levelKey" yaml:"levelKey"`
TimeKey string `json:"timeKey" yaml:"timeKey"`
CallerKey string `json:"callerKey" yaml:"callerKey"`
FunctionKey string `json:"functionKey" yaml:"functionKey"`
StacktraceKey string `json:"stacktraceKey" yaml:"stacktraceKey"`
ConsoleSeparator string `json:"consoleSeparator" yaml:"consoleSeparator"`
EncodeTime TimeEncoder
EncodeLevel LevelEncoder
EncodeCaller CallerEncoder
}
type Formatter interface {
Format(config *EncoderConfig, entry *Entry) (*pools.Buffer, error)
}

View File

@ -0,0 +1,144 @@
package log
import (
"encoding/json"
"time"
"go_dreamfactory/lego/utils/pools"
)
func NewConsoleEncoder() Formatter {
return &ConsoleFormatter{}
}
type ConsoleFormatter struct {
*EncoderConfig
}
func (this *ConsoleFormatter) Format(config *EncoderConfig, entry *Entry) (*pools.Buffer, error) {
line := pools.BufferPoolGet()
isfirst := true
if config.TimeKey != "" && config.EncodeTime != nil {
line.AppendString(config.EncodeTime(entry.Time))
isfirst = false
}
if config.LevelKey != "" && config.EncodeLevel != nil {
if !isfirst {
line.AppendString(config.ConsoleSeparator)
}
isfirst = false
line.AppendString(config.EncodeLevel(entry.Level))
}
if entry.Caller.Defined {
if config.CallerKey != "" && config.EncodeCaller != nil {
if !isfirst {
line.AppendString(config.ConsoleSeparator)
}
isfirst = false
line.AppendString(config.EncodeCaller(entry.Caller))
}
if config.FunctionKey != "" {
if !isfirst {
line.AppendString(config.ConsoleSeparator)
}
isfirst = false
line.AppendString(entry.Caller.Function)
}
}
if entry.Name != "" {
if !isfirst {
line.AppendString(config.ConsoleSeparator)
}
isfirst = false
line.AppendString("[")
line.AppendString(entry.Name)
line.AppendString("]")
}
if config.MessageKey != "" {
if !isfirst {
line.AppendString(config.ConsoleSeparator)
}
isfirst = false
line.AppendString(entry.Message)
}
for _, v := range entry.Data {
if !isfirst {
line.AppendString(config.ConsoleSeparator)
}
isfirst = false
line.AppendString(v.Key)
line.AppendString(":")
writetoline(line, v.Value)
}
if entry.Caller.Stack != "" && config.StacktraceKey != "" {
line.AppendString("\n")
line.AppendString(entry.Caller.Stack)
}
line.AppendString("\n")
return line, nil
}
func writetoline(line *pools.Buffer, v interface{}) {
switch v := v.(type) {
case nil:
line.AppendString("nil")
break
case string:
line.AppendString(v)
break
case []byte:
line.AppendBytes(v)
break
case int:
line.AppendInt(int64(v))
break
case int8:
line.AppendInt(int64(v))
break
case int16:
line.AppendInt(int64(v))
break
case int32:
line.AppendInt(int64(v))
break
case int64:
line.AppendInt(int64(v))
break
case uint:
line.AppendUint(uint64(v))
break
case uint8:
line.AppendUint(uint64(v))
break
case uint16:
line.AppendUint(uint64(v))
break
case uint32:
line.AppendUint(uint64(v))
break
case uint64:
line.AppendUint(uint64(v))
break
case float32:
line.AppendFloat(float64(v), 64)
break
case float64:
line.AppendFloat(v, 64)
break
case bool:
line.AppendBool(v)
break
case time.Time:
line.AppendTime(v, time.RFC3339Nano)
break
case time.Duration:
line.AppendInt(v.Nanoseconds())
break
default:
d, _ := json.Marshal(v)
line.AppendBytes(d)
break
}
}

59
lego/sys/log/level.go Normal file
View File

@ -0,0 +1,59 @@
package log
import "fmt"
type LevelEnabler interface {
Enabled(Loglevel) bool
}
type Loglevel int8
const (
PanicLevel Loglevel = iota
FatalLevel
ErrorLevel
WarnLevel
InfoLevel
DebugLevel
)
func (l Loglevel) String() string {
switch l {
case DebugLevel:
return "debug"
case InfoLevel:
return "info"
case WarnLevel:
return "warn"
case ErrorLevel:
return "error"
case PanicLevel:
return "panic"
case FatalLevel:
return "fatal"
default:
return fmt.Sprintf("Level(%d)", l)
}
}
func (l Loglevel) CapitalString() string {
switch l {
case DebugLevel:
return "DEBUG"
case InfoLevel:
return "INFO"
case WarnLevel:
return "WARN"
case ErrorLevel:
return "ERROR"
case PanicLevel:
return "PANIC"
case FatalLevel:
return "FATAL"
default:
return fmt.Sprintf("LEVEL(%d)", l)
}
}
func (l Loglevel) Enabled(lvl Loglevel) bool {
return lvl <= l
}

231
lego/sys/log/logger.go Normal file
View File

@ -0,0 +1,231 @@
package log
import (
"fmt"
"os"
"time"
"go_dreamfactory/lego/utils/pools"
)
func newSys(options *Options) (sys *Logger, err error) {
hook := LogFileOut{
Filename: options.FileName, //日志文件路径
MaxAge: options.MaxAgeTime, //备份日志保存天数
CupTime: time.Duration(options.CupTimeTime) * time.Hour, //日志切割间隔时间
Compress: options.Compress, //是否压缩 disabled by default
MaxBackups: options.MaxBackups, //最大备份数
LocalTime: true, //使用本地时间
}
if err = hook.openNew(); err != nil {
return
}
out := make(writeTree, 0, 2)
out = append(out, AddSync(&hook))
if options.IsDebug {
out = append(out, Lock(os.Stdout))
}
sys = &Logger{
config: NewDefEncoderConfig(),
formatter: NewConsoleEncoder(),
out: out,
level: options.Loglevel,
addCaller: options.ReportCaller,
callerSkip: options.CallerSkip,
addStack: FatalLevel,
}
return
}
type Logger struct {
config *EncoderConfig //编码配置
level LevelEnabler //日志输出级别
formatter Formatter //日志格式化
name string //日志标签
out IWrite //日志输出
addCaller bool //是否打印堆栈信息
addStack LevelEnabler //堆栈信息输出级别
callerSkip int //堆栈输出深度
}
func (this *Logger) Clone(name string, skip int) ILogger {
return &Logger{
config: this.config,
formatter: this.formatter,
name: name,
out: this.out,
level: this.level,
addCaller: this.addCaller,
callerSkip: skip,
addStack: this.addStack,
}
}
func (this *Logger) SetName(name string) {
this.name = name
}
func (this *Logger) Enabled(lvl Loglevel) bool {
return this.level.Enabled(lvl)
}
func (this *Logger) Debug(msg string, args ...Field) {
this.Log(DebugLevel, msg, args...)
}
func (this *Logger) Info(msg string, args ...Field) {
this.Log(InfoLevel, msg, args...)
}
func (this *Logger) Print(msg string, args ...Field) {
this.Log(InfoLevel, msg, args...)
}
func (this *Logger) Warn(msg string, args ...Field) {
this.Log(WarnLevel, msg, args...)
}
func (this *Logger) Error(msg string, args ...Field) {
this.Log(ErrorLevel, msg, args...)
}
func (this *Logger) Panic(msg string, args ...Field) {
this.Log(PanicLevel, msg, args...)
}
func (this *Logger) Fatal(msg string, args ...Field) {
this.Log(FatalLevel, msg, args...)
os.Exit(1)
}
func (this *Logger) Log(level Loglevel, msg string, args ...Field) {
if this.level.Enabled(level) {
this.log(level, msg, args...)
}
}
func (this *Logger) Debugf(format string, args ...interface{}) {
this.Logf(DebugLevel, format, args...)
}
func (this *Logger) Infof(format string, args ...interface{}) {
this.Logf(InfoLevel, format, args...)
}
func (this *Logger) Printf(format string, args ...interface{}) {
this.Logf(InfoLevel, format, args...)
}
func (this *Logger) Warnf(format string, args ...interface{}) {
this.Logf(WarnLevel, format, args...)
}
func (this *Logger) Errorf(format string, args ...interface{}) {
this.Logf(ErrorLevel, format, args...)
}
func (this *Logger) Fatalf(format string, args ...interface{}) {
this.Logf(FatalLevel, format, args...)
os.Exit(1)
}
func (this *Logger) Panicf(format string, args ...interface{}) {
this.Logf(PanicLevel, format, args...)
}
func (this *Logger) Logf(level Loglevel, format string, args ...interface{}) {
if this.level.Enabled(level) {
this.log(level, fmt.Sprintf(format, args...))
}
}
func (this *Logger) Debugln(args ...interface{}) {
this.Logln(DebugLevel, args...)
}
func (this *Logger) Infoln(args ...interface{}) {
this.Logln(InfoLevel, args...)
}
func (this *Logger) Println(args ...interface{}) {
this.Logln(InfoLevel, args...)
}
func (this *Logger) Warnln(args ...interface{}) {
this.Logln(WarnLevel, args...)
}
func (this *Logger) Errorln(args ...interface{}) {
this.Logln(ErrorLevel, args...)
}
func (this *Logger) Fatalln(args ...interface{}) {
this.Logln(FatalLevel, args...)
os.Exit(1)
}
func (this *Logger) Panicln(args ...interface{}) {
this.Logln(PanicLevel, args...)
}
func (this *Logger) Logln(level Loglevel, args ...interface{}) {
if this.level.Enabled(level) {
this.log(level, this.sprintlnn(args...))
}
}
func (this *Logger) log(level Loglevel, msg string, args ...Field) {
entry := this.check(level, msg, args...)
this.write(entry)
if level <= PanicLevel {
panic(entry)
}
putEntry(entry)
}
func (this *Logger) check(level Loglevel, msg string, args ...Field) (entry *Entry) {
entry = getEntry()
entry.Name = this.name
entry.Time = time.Now()
entry.Level = level
entry.Message = msg
entry.WithFields(args...)
addStack := this.addStack.Enabled(level)
if !this.addCaller && !addStack {
return
}
stackDepth := stacktraceFirst
if addStack {
stackDepth = stacktraceFull
}
stack := captureStacktrace(this.callerSkip+callerSkipOffset, stackDepth)
defer stack.Free()
if stack.Count() == 0 {
if this.addCaller {
if entry.Err != "" {
entry.Err = entry.Err + ",error: failed to get caller"
} else {
entry.Err = "error:failed to get caller"
}
}
return
}
frame, more := stack.Next()
if this.addCaller {
entry.Caller.Defined = frame.PC != 0
entry.Caller.PC = frame.PC
entry.Caller.File = frame.File
entry.Caller.Line = frame.Line
entry.Caller.Function = frame.Function
}
if addStack {
buffer := pools.BufferPoolGet()
defer buffer.Free()
stackfmt := newStackFormatter(buffer)
stackfmt.FormatFrame(frame)
if more {
stackfmt.FormatStack(stack)
}
entry.Caller.Stack = buffer.String()
}
return
}
func (this *Logger) write(entry *Entry) {
buf, err := this.formatter.Format(this.config, entry)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
return
}
err = this.out.WriteTo(buf.Bytes())
buf.Free()
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to obtain write, %v\n", err)
return
}
if entry.Level < ErrorLevel {
this.out.Sync()
}
return
}
func (this *Logger) sprintlnn(args ...interface{}) string {
msg := fmt.Sprintln(args...)
return msg[:len(msg)-1]
}

View File

@ -1,114 +1,139 @@
package log
import (
"errors"
"go_dreamfactory/lego/utils/mapstructure"
)
type Loglevel int8
const (
DebugLevel Loglevel = iota
InfoLevel
WarnLevel
ErrorLevel
PanicLevel
FatalLevel
)
type LogEncoder int8
const (
Console LogEncoder = iota
JSON
TextEncoder LogEncoder = iota
JSONEncoder
)
type Option func(*Options)
type Options struct {
FileName string //日志文件名包含
Loglevel Loglevel //日志输出级别
Debugmode bool //是否debug模式
IsDebug bool //是否是开发模式
ReportCaller bool //是否输出堆栈信息
CallerSkip int //堆栈深度
Encoder LogEncoder //日志输出样式
Loglayer int //日志堆栈信息打印层级
LogMaxSize int //每个日志文件最大尺寸 单位 M 默认 1024M
LogMaxBackups int //最多保留备份个数 默认 10个
LogMaxAge int //文件最多保存多少天 默认 7天
CupTimeTime int //日志分割时间 单位 小时
MaxAgeTime int //日志最大保存时间 单位天
MaxBackups int //最大备份日志个数
Compress bool //是否压缩备份日志
}
///日志文件名包含
func SetFileName(v string) Option {
return func(o *Options) {
o.FileName = v
}
}
//是否是开发模式
func SetIsDebug(v bool) Option {
return func(o *Options) {
o.IsDebug = v
}
}
///日志输出级别 debug info warning error fatal panic
func SetLoglevel(v Loglevel) Option {
return func(o *Options) {
o.Loglevel = v
}
}
func SetDebugMode(v bool) Option {
func SetReportCaller(v bool) Option {
return func(o *Options) {
o.Debugmode = v
o.ReportCaller = v
}
}
func SetCallerSkip(v int) Option {
return func(o *Options) {
o.CallerSkip = v
}
}
///日志输出样式
func SetEncoder(v LogEncoder) Option {
return func(o *Options) {
o.Encoder = v
}
}
func SetLoglayer(v int) Option {
///日志分割时间 单位 小时
func SetRotationTime(v int) Option {
return func(o *Options) {
o.Loglayer = v
}
}
func SetLogMaxSize(v int) Option {
return func(o *Options) {
o.LogMaxSize = v
}
}
func SetLogMaxBackups(v int) Option {
return func(o *Options) {
o.LogMaxBackups = v
}
}
func SetLogMaxAge(v int) Option {
return func(o *Options) {
o.LogMaxAge = v
o.CupTimeTime = v
}
}
func newOptions(config map[string]interface{}, opts ...Option) Options {
options := Options{
FileName: "./lego.log",
Loglevel: WarnLevel,
Debugmode: false,
Encoder: Console,
Loglayer: 2,
LogMaxSize: 1024,
LogMaxBackups: 10,
LogMaxAge: 7,
///日志最大保存时间 单位天
func SetMaxAgeTime(v int) Option {
return func(o *Options) {
o.MaxAgeTime = v
}
}
///日志备份最大文件数
func SetMaxBackups(v int) Option {
return func(o *Options) {
o.MaxBackups = v
}
}
///是否压缩备份日志
func SetCompress(v bool) Option {
return func(o *Options) {
o.Compress = v
}
}
func newOptions(config map[string]interface{}, opts ...Option) (options *Options, err error) {
options = &Options{
FileName: "log",
Loglevel: DebugLevel,
CupTimeTime: 24,
MaxAgeTime: 7,
MaxBackups: 250,
Compress: false,
Encoder: TextEncoder,
CallerSkip: 0,
ReportCaller: false,
IsDebug: true,
}
if config != nil {
mapstructure.Decode(config, &options)
mapstructure.Decode(config, options)
}
for _, o := range opts {
o(&options)
o(options)
}
return options
if options.CupTimeTime <= 0 || options.MaxAgeTime <= 0 {
err = errors.New("log options RotationTime or MaxAgeTime is zero!")
return
}
return
}
func newOptionsByOption(opts ...Option) Options {
options := Options{
FileName: "./lego.log",
Loglevel: WarnLevel,
Debugmode: false,
Loglayer: 2,
LogMaxSize: 1024,
LogMaxBackups: 10,
LogMaxAge: 7,
func newOptionsByOption(opts ...Option) (options *Options, err error) {
options = &Options{
FileName: "log.log",
Loglevel: DebugLevel,
CupTimeTime: 24,
MaxAgeTime: 7,
MaxBackups: 250,
Compress: false,
Encoder: TextEncoder,
CallerSkip: 0,
ReportCaller: false,
IsDebug: true,
}
for _, o := range opts {
o(&options)
o(options)
}
return options
return
}

156
lego/sys/log/stacktrace.go Normal file
View File

@ -0,0 +1,156 @@
package log
import (
"runtime"
"sync"
"go_dreamfactory/lego/utils/pools"
)
var _stacktracePool = sync.Pool{
New: func() interface{} {
return &stacktrace{
storage: make([]uintptr, 64),
}
},
}
type stacktrace struct {
pcs []uintptr // program counters; always a subslice of storage
frames *runtime.Frames
// The size of pcs varies depending on requirements:
// it will be one if the only the first frame was requested,
// and otherwise it will reflect the depth of the call stack.
//
// storage decouples the slice we need (pcs) from the slice we pool.
// We will always allocate a reasonably large storage, but we'll use
// only as much of it as we need.
storage []uintptr
}
// stacktraceDepth specifies how deep of a stack trace should be captured.
type stacktraceDepth int
const callerSkipOffset = 2
const (
// stacktraceFirst captures only the first frame.
stacktraceFirst stacktraceDepth = iota
// stacktraceFull captures the entire call stack, allocating more
// storage for it if needed.
stacktraceFull
)
// captureStacktrace captures a stack trace of the specified depth, skipping
// the provided number of frames. skip=0 identifies the caller of
// captureStacktrace.
//
// The caller must call Free on the returned stacktrace after using it.
func captureStacktrace(skip int, depth stacktraceDepth) *stacktrace {
stack := _stacktracePool.Get().(*stacktrace)
switch depth {
case stacktraceFirst:
stack.pcs = stack.storage[:1]
case stacktraceFull:
stack.pcs = stack.storage
}
// Unlike other "skip"-based APIs, skip=0 identifies runtime.Callers
// itself. +2 to skip captureStacktrace and runtime.Callers.
numFrames := runtime.Callers(
skip+2,
stack.pcs,
)
// runtime.Callers truncates the recorded stacktrace if there is no
// room in the provided slice. For the full stack trace, keep expanding
// storage until there are fewer frames than there is room.
if depth == stacktraceFull {
pcs := stack.pcs
for numFrames == len(pcs) {
pcs = make([]uintptr, len(pcs)*2)
numFrames = runtime.Callers(skip+2, pcs)
}
// Discard old storage instead of returning it to the pool.
// This will adjust the pool size over time if stack traces are
// consistently very deep.
stack.storage = pcs
stack.pcs = pcs[:numFrames]
} else {
stack.pcs = stack.pcs[:numFrames]
}
stack.frames = runtime.CallersFrames(stack.pcs)
return stack
}
// Free releases resources associated with this stacktrace
// and returns it back to the pool.
func (st *stacktrace) Free() {
st.frames = nil
st.pcs = nil
_stacktracePool.Put(st)
}
// Count reports the total number of frames in this stacktrace.
// Count DOES NOT change as Next is called.
func (st *stacktrace) Count() int {
return len(st.pcs)
}
// Next returns the next frame in the stack trace,
// and a boolean indicating whether there are more after it.
func (st *stacktrace) Next() (_ runtime.Frame, more bool) {
return st.frames.Next()
}
func takeStacktrace(skip int) string {
stack := captureStacktrace(skip+1, stacktraceFull)
defer stack.Free()
buffer := pools.BufferPoolGet()
defer buffer.Free()
stackfmt := newStackFormatter(buffer)
stackfmt.FormatStack(stack)
return buffer.String()
}
// stackFormatter formats a stack trace into a readable string representation.
type stackFormatter struct {
b *pools.Buffer
nonEmpty bool // whehther we've written at least one frame already
}
// newStackFormatter builds a new stackFormatter.
func newStackFormatter(b *pools.Buffer) stackFormatter {
return stackFormatter{b: b}
}
// FormatStack formats all remaining frames in the provided stacktrace -- minus
// the final runtime.main/runtime.goexit frame.
func (sf *stackFormatter) FormatStack(stack *stacktrace) {
// Note: On the last iteration, frames.Next() returns false, with a valid
// frame, but we ignore this frame. The last frame is a a runtime frame which
// adds noise, since it's only either runtime.main or runtime.goexit.
for frame, more := stack.Next(); more; frame, more = stack.Next() {
sf.FormatFrame(frame)
}
}
// FormatFrame formats the given frame.
func (sf *stackFormatter) FormatFrame(frame runtime.Frame) {
if sf.nonEmpty {
sf.b.AppendByte('\n')
}
sf.nonEmpty = true
sf.b.AppendString(frame.Function)
sf.b.AppendByte('\n')
sf.b.AppendByte('\t')
sf.b.AppendString(frame.File)
sf.b.AppendByte(':')
sf.b.AppendInt(int64(frame.Line))
}

View File

@ -13,14 +13,18 @@ type TestData struct {
Age int32
}
var sys log.ILog
func (this *TestData) Log() {
sys.Error("妈妈咪呀!")
}
var sys log.ISys
func TestMain(m *testing.M) {
var err error
if sys, err = log.NewSys(
log.SetFileName("./log.log"),
log.SetDebugMode(false),
log.SetLoglayer(2),
log.SetFileName("log.log"),
log.SetIsDebug(false),
log.SetEncoder(log.TextEncoder),
); err != nil {
fmt.Println(err)
return
@ -28,10 +32,12 @@ func TestMain(m *testing.M) {
defer os.Exit(m.Run())
}
func Test_sys(t *testing.T) {
sys.Error("测试日志接口代码!")
data := &TestData{}
data.Log()
}
func Benchmark_Ability_Zap(b *testing.B) {
//性能测试
func Benchmark_Ability(b *testing.B) {
for i := 0; i < b.N; i++ { //use b.N for looping
sys.Error("妈妈咪呀!")
}

132
lego/sys/log/turnlog.go Normal file
View File

@ -0,0 +1,132 @@
package log
func NewTurnlog(isturnon bool, log ILogger) ILogger {
return &Turnlog{
isturnon: isturnon,
log: log,
}
}
type Turnlog struct {
isturnon bool
log ILogger
}
func (this *Turnlog) SetName(name string) {
if this.log != nil {
this.log.SetName(name)
}
}
func (this *Turnlog) Enabled(lvl Loglevel) bool {
if this.isturnon && this.log != nil {
return this.log.Enabled(lvl)
} else {
return false
}
}
func (this *Turnlog) Debug(msg string, args ...Field) {
if this.isturnon && this.log != nil {
this.log.Debug(msg, args...)
}
}
func (this *Turnlog) Info(msg string, args ...Field) {
if this.isturnon && this.log != nil {
this.log.Info(msg, args...)
}
}
func (this *Turnlog) Print(msg string, args ...Field) {
if this.isturnon && this.log != nil {
this.log.Print(msg, args...)
}
}
func (this *Turnlog) Warn(msg string, args ...Field) {
if this.isturnon && this.log != nil {
this.log.Warn(msg, args...)
}
}
func (this *Turnlog) Error(msg string, args ...Field) {
if this.log != nil {
this.log.Error(msg, args...)
}
}
func (this *Turnlog) Panic(msg string, args ...Field) {
if this.log != nil {
this.log.Panic(msg, args...)
}
}
func (this *Turnlog) Fatal(msg string, args ...Field) {
if this.log != nil {
this.log.Fatal(msg, args...)
}
}
func (this *Turnlog) Debugf(format string, args ...interface{}) {
if this.isturnon && this.log != nil {
this.log.Debugf(format, args...)
}
}
func (this *Turnlog) Infof(format string, args ...interface{}) {
if this.isturnon && this.log != nil {
this.log.Infof(format, args...)
}
}
func (this *Turnlog) Printf(format string, args ...interface{}) {
if this.isturnon && this.log != nil {
this.log.Printf(format, args...)
}
}
func (this *Turnlog) Warnf(format string, args ...interface{}) {
if this.isturnon && this.log != nil {
this.log.Warnf(format, args...)
}
}
func (this *Turnlog) Errorf(format string, args ...interface{}) {
if this.log != nil {
this.log.Errorf(format, args...)
}
}
func (this *Turnlog) Fatalf(format string, args ...interface{}) {
if this.log != nil {
this.log.Fatalf(format, args...)
}
}
func (this *Turnlog) Panicf(format string, args ...interface{}) {
if this.log != nil {
this.log.Panicf(format, args...)
}
}
func (this *Turnlog) Debugln(args ...interface{}) {
if this.isturnon && this.log != nil {
this.log.Debugln(args...)
}
}
func (this *Turnlog) Infoln(args ...interface{}) {
if this.isturnon && this.log != nil {
this.log.Infoln(args...)
}
}
func (this *Turnlog) Println(args ...interface{}) {
if this.isturnon && this.log != nil {
this.log.Println(args...)
}
}
func (this *Turnlog) Warnln(args ...interface{}) {
if this.isturnon && this.log != nil {
this.log.Warnln(args...)
}
}
func (this *Turnlog) Errorln(args ...interface{}) {
if this.log != nil {
this.log.Errorln(args...)
}
}
func (this *Turnlog) Fatalln(args ...interface{}) {
if this.log != nil {
this.log.Fatalln(args...)
}
}
func (this *Turnlog) Panicln(args ...interface{}) {
if this.log != nil {
this.log.Panicln(args...)
}
}

View File

@ -0,0 +1,87 @@
package log
import (
"io"
"sync"
"go.uber.org/multierr"
)
func AddWrites(w ...IWrite) IWrite {
ws := make(writeTree, 0, len(w))
for _, v := range w {
ws = append(ws, v)
}
return ws
}
type writeTree []IWrite
func (mc writeTree) WriteTo(bs []byte) error {
var err error
for i := range mc {
err = multierr.Append(err, mc[i].WriteTo(bs))
}
return err
}
func (mc writeTree) Sync() error {
var err error
for i := range mc {
err = multierr.Append(err, mc[i].Sync())
}
return err
}
type IWriteSyncer interface {
io.Writer
Sync() error
}
type IWrite interface {
WriteTo(bs []byte) error
Sync() error
}
func AddSync(w io.Writer) IWrite {
switch w := w.(type) {
case IWrite:
return w
default:
return writerWrapper{w}
}
}
type writerWrapper struct {
io.Writer
}
func (w writerWrapper) WriteTo(bs []byte) error {
_, err := w.Write(bs)
return err
}
func (w writerWrapper) Sync() error {
return nil
}
func Lock(w IWriteSyncer) IWrite {
return &lockedWriteSyncer{w: w}
}
type lockedWriteSyncer struct {
sync.Mutex
w IWriteSyncer
}
func (s *lockedWriteSyncer) WriteTo(bs []byte) error {
s.Lock()
_, err := s.w.Write(bs)
s.Unlock()
return err
}
func (s *lockedWriteSyncer) Sync() error {
s.Lock()
err := s.w.Sync()
s.Unlock()
return err
}

View File

@ -1,190 +0,0 @@
package log
import (
"os"
"time"
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
func newSys(options Options) (sys *Logger, err error) {
createlogfile(options.FileName)
var allCore []zapcore.Core
hook := lumberjack.Logger{
Filename: options.FileName, //日志文件路径
MaxSize: options.LogMaxSize, //每个日志文件保存的最大尺寸 单位M
MaxBackups: options.LogMaxBackups, //最多保留备份个数
MaxAge: options.LogMaxAge, //文件最多保存多少天
Compress: false, //是否压缩 disabled by default
LocalTime: true, //使用本地时间
}
var level zapcore.Level
switch options.Loglevel {
case DebugLevel:
level = zap.DebugLevel
case InfoLevel:
level = zap.InfoLevel
case WarnLevel:
level = zap.WarnLevel
case ErrorLevel:
level = zap.ErrorLevel
case PanicLevel:
level = zap.PanicLevel
case FatalLevel:
level = zap.FatalLevel
default:
level = zap.InfoLevel
}
fileWriter := zapcore.AddSync(&hook)
consoleDebugging := zapcore.Lock(os.Stdout)
var encoderConfig zapcore.EncoderConfig
timeFormat := func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format("2006/01/02 15:04:05.000"))
}
_, err = os.OpenFile(options.FileName, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
if err != nil {
return
}
if options.Debugmode {
//重新生成文件
encoderConfig = zap.NewDevelopmentEncoderConfig()
encoderConfig.EncodeTime = timeFormat
allCore = append(allCore, zapcore.NewCore(zapcore.NewConsoleEncoder(encoderConfig), consoleDebugging, level))
} else {
encoderConfig = zap.NewProductionEncoderConfig()
encoderConfig.EncodeTime = timeFormat
}
if options.Encoder == Console {
allCore = append(allCore, zapcore.NewCore(zapcore.NewConsoleEncoder(encoderConfig), fileWriter, level))
} else {
allCore = append(allCore, zapcore.NewCore(zapcore.NewJSONEncoder(encoderConfig), fileWriter, level))
}
core := zapcore.NewTee(allCore...)
tlog := zap.New(core).WithOptions(zap.AddCaller(), zap.AddCallerSkip(options.Loglayer))
sys = &Logger{
core: core,
tlog: tlog,
log: tlog.Sugar(),
}
return
}
type Logger struct {
core zapcore.Core
tlog *zap.Logger
log *zap.SugaredLogger
}
func FieldTozapField(fields ...Field) (fds []zap.Field) {
fds = make([]zap.Field, 0)
for _, v := range fields {
field := zap.Field{Key: v.Key}
switch v.Value.(type) {
case []byte:
field.Type = zapcore.BinaryType
field.Interface = v.Value
case bool:
field.Type = zapcore.BoolType
if v.Value.(bool) {
field.Integer = 1
} else {
field.Integer = 0
}
case byte:
field.Type = zapcore.Uint8Type
field.Integer = int64(v.Value.(byte))
case time.Duration:
field.Type = zapcore.DurationType
field.Integer = int64(v.Value.(time.Duration))
case float64:
field.Type = zapcore.Float64Type
field.Integer = v.Value.(int64)
case float32:
field.Type = zapcore.Float32Type
field.Integer = v.Value.(int64)
case int64:
field.Type = zapcore.Int64Type
field.Integer = v.Value.(int64)
case uint64:
field.Type = zapcore.Uint64Type
field.Integer = int64(v.Value.(uint64))
case int32:
field.Type = zapcore.Int32Type
field.Integer = int64(v.Value.(int32))
case uint32:
field.Type = zapcore.Uint64Type
field.Integer = int64(v.Value.(uint32))
case int16:
field.Type = zapcore.Int16Type
field.Integer = int64(v.Value.(int16))
case uint16:
field.Type = zapcore.Uint64Type
field.Integer = int64(v.Value.(uint16))
case int8:
field.Type = zapcore.Int8Type
field.Integer = int64(v.Value.(int8))
case string:
field.Type = zapcore.StringType
field.String = v.Value.(string)
case LogStrut:
field.Type = zapcore.StringType
field.String = v.Value.(LogStrut).ToString()
default:
field.Type = zapcore.UnknownType
field.Interface = v.Value
}
fds = append(fds, field)
}
return
}
func (this *Logger) Clone(option ...Option) (sys ILog) {
options := newOptionsByOption(option...)
tlog := zap.New(this.core).WithOptions(zap.AddCaller(), zap.AddCallerSkip(options.Loglayer))
sys = &Logger{
core: this.core,
tlog: tlog,
log: tlog.Sugar(),
}
return
}
func (this *Logger) Debug(msg string, fields ...Field) {
this.tlog.Debug(msg, FieldTozapField(fields...)...)
}
func (this *Logger) Info(msg string, fields ...Field) {
this.tlog.Info(msg, FieldTozapField(fields...)...)
}
func (this *Logger) Warn(msg string, fields ...Field) {
this.tlog.Warn(msg, FieldTozapField(fields...)...)
}
func (this *Logger) Error(msg string, fields ...Field) {
this.tlog.Error(msg, FieldTozapField(fields...)...)
}
func (this *Logger) Panic(msg string, fields ...Field) {
this.tlog.Panic(msg, FieldTozapField(fields...)...)
}
func (this *Logger) Fatal(msg string, fields ...Field) {
this.tlog.Fatal(msg, FieldTozapField(fields...)...)
}
func (this *Logger) Debugf(format string, a ...interface{}) {
this.log.Debugf(format, a...)
}
func (this *Logger) Infof(format string, a ...interface{}) {
this.log.Infof(format, a...)
}
func (this *Logger) Warnf(format string, a ...interface{}) {
this.log.Warnf(format, a...)
}
func (this *Logger) Errorf(format string, a ...interface{}) {
this.log.Errorf(format, a...)
}
func (this *Logger) Panicf(format string, a ...interface{}) {
this.log.Panicf(format, a...)
}
func (this *Logger) Fatalf(format string, a ...interface{}) {
this.log.Fatalf(format, a...)
}

View File

@ -1,98 +0,0 @@
package nacos
import (
"github.com/nacos-group/nacos-sdk-go/model"
"github.com/nacos-group/nacos-sdk-go/vo"
)
type (
ISys interface {
Naming_RegisterInstance(service vo.RegisterInstanceParam) (success bool, err error)
Naming_DeregisterInstance(service vo.DeregisterInstanceParam) (success bool, err error)
Naming_GetService(param vo.GetServiceParam) (services model.Service, err error)
Naming_SelectAllInstances(param vo.SelectAllInstancesParam) (instances []model.Instance, err error)
Naming_SelectInstances(param vo.SelectInstancesParam) (instances []model.Instance, err error)
Naming_SelectOneHealthyInstance(param vo.SelectOneHealthInstanceParam) (instance *model.Instance, err error)
Naming_Subscribe(param *vo.SubscribeParam) (err error)
Naming_Unsubscribe(param *vo.SubscribeParam) (err error)
Naming_GetAllServicesInfo(param vo.GetAllServiceInfoParam) (serviceInfos model.ServiceList, err error)
Config_GetConfig(param vo.ConfigParam) (string, error)
Config_PublishConfig(param vo.ConfigParam) (bool, error)
Config_DeleteConfig(param vo.ConfigParam) (bool, error)
Config_ListenConfig(params vo.ConfigParam) (err error)
Config_CancelListenConfig(params vo.ConfigParam) (err error)
Config_SearchConfig(param vo.SearchConfigParam) (*model.ConfigPage, error)
Config_PublishAggr(param vo.ConfigParam) (published bool, err error)
}
)
var (
defsys ISys
)
func OnInit(config map[string]interface{}, option ...Option) (err error) {
defsys, err = newSys(newOptions(config, option...))
return
}
func NewSys(option ...Option) (sys ISys, err error) {
sys, err = newSys(newOptionsByOption(option...))
return
}
///注册服务
func Naming_RegisterInstance(service vo.RegisterInstanceParam) (success bool, err error) {
return defsys.Naming_RegisterInstance(service)
}
///注销服务
func Naming_DeregisterInstance(service vo.DeregisterInstanceParam) (success bool, err error) {
return defsys.Naming_DeregisterInstance(service)
}
///获取服务
func Naming_GetService(param vo.GetServiceParam) (services model.Service, err error) {
return defsys.Naming_GetService(param)
}
///获取全部服务实例
func Naming_SelectAllInstances(param vo.SelectAllInstancesParam) (instances []model.Instance, err error) {
return defsys.Naming_SelectAllInstances(param)
}
func Naming_SelectInstances(param vo.SelectInstancesParam) (instances []model.Instance, err error) {
return defsys.Naming_SelectInstances(param)
}
func Naming_SelectOneHealthyInstance(param vo.SelectOneHealthInstanceParam) (instance *model.Instance, err error) {
return defsys.Naming_SelectOneHealthyInstance(param)
}
func Naming_Subscribe(param *vo.SubscribeParam) (err error) {
return defsys.Naming_Subscribe(param)
}
func Naming_Unsubscribe(param *vo.SubscribeParam) (err error) {
return defsys.Naming_Unsubscribe(param)
}
func Naming_GetAllServicesInfo(param vo.GetAllServiceInfoParam) (serviceInfos model.ServiceList, err error) {
return defsys.Naming_GetAllServicesInfo(param)
}
func Config_GetConfig(param vo.ConfigParam) (string, error) {
return defsys.Config_GetConfig(param)
}
func Config_PublishConfig(param vo.ConfigParam) (bool, error) {
return defsys.Config_PublishConfig(param)
}
func Config_DeleteConfig(param vo.ConfigParam) (bool, error) {
return defsys.Config_DeleteConfig(param)
}
func Config_ListenConfig(params vo.ConfigParam) (err error) {
return defsys.Config_ListenConfig(params)
}
func Config_CancelListenConfig(params vo.ConfigParam) (err error) {
return defsys.Config_ListenConfig(params)
}
func Config_SearchConfig(param vo.SearchConfigParam) (*model.ConfigPage, error) {
return defsys.Config_SearchConfig(param)
}
func Config_PublishAggr(param vo.ConfigParam) (published bool, err error) {
return defsys.Config_PublishAggr(param)
}

View File

@ -1,143 +0,0 @@
package nacos
import (
"github.com/nacos-group/nacos-sdk-go/clients"
"github.com/nacos-group/nacos-sdk-go/clients/config_client"
"github.com/nacos-group/nacos-sdk-go/clients/naming_client"
"github.com/nacos-group/nacos-sdk-go/common/constant"
"github.com/nacos-group/nacos-sdk-go/model"
"github.com/nacos-group/nacos-sdk-go/vo"
)
func newSys(options Options) (sys *Nacos, err error) {
sys = &Nacos{
options: options,
}
// 创建clientConfig
clientConfig := constant.ClientConfig{
NamespaceId: options.NamespaceId,
TimeoutMs: options.TimeoutMs,
NotLoadCacheAtStart: true,
Username: options.Username,
Password: options.Password,
LogDir: "./nacos/log",
CacheDir: "./nacos/cache",
RotateTime: "1h",
MaxAge: 3,
LogLevel: "debug",
}
// 至少一个ServerConfig
serverConfigs := []constant.ServerConfig{
{
IpAddr: options.NacosAddr,
ContextPath: "/nacos",
Port: options.Port,
Scheme: "http",
},
}
if sys.options.NacosClientType == NamingClient || sys.options.NacosClientType == All {
// 创建服务发现客户端的另一种方式 (推荐)
sys.namingClient, err = clients.NewNamingClient(
vo.NacosClientParam{
ClientConfig: &clientConfig,
ServerConfigs: serverConfigs,
},
)
}
if sys.options.NacosClientType == ConfigClient || sys.options.NacosClientType == All {
// 创建服务发现客户端的另一种方式 (推荐)
sys.configClient, err = clients.NewConfigClient(
vo.NacosClientParam{
ClientConfig: &clientConfig,
ServerConfigs: serverConfigs,
},
)
}
return
}
type Nacos struct {
options Options
namingClient naming_client.INamingClient
configClient config_client.IConfigClient
}
///注册服务
func (this *Nacos) Naming_RegisterInstance(service vo.RegisterInstanceParam) (success bool, err error) {
success, err = this.namingClient.RegisterInstance(service)
return
}
///注销服务
func (this *Nacos) Naming_DeregisterInstance(service vo.DeregisterInstanceParam) (success bool, err error) {
success, err = this.namingClient.DeregisterInstance(service)
return
}
///获取服务
func (this *Nacos) Naming_GetService(param vo.GetServiceParam) (services model.Service, err error) {
services, err = this.namingClient.GetService(param)
return
}
/// SelectAllInstance可以返回全部实例列表,包括healthy=false,enable=false,weight<=0
func (this *Nacos) Naming_SelectAllInstances(param vo.SelectAllInstancesParam) (instances []model.Instance, err error) {
instances, err = this.namingClient.SelectAllInstances(param)
return
}
///选中实例列表
func (this *Nacos) Naming_SelectInstances(param vo.SelectInstancesParam) (instances []model.Instance, err error) {
instances, err = this.namingClient.SelectInstances(param)
return
}
/// SelectOneHealthyInstance将会按加权随机轮询的负载均衡策略返回一个健康的实例 实例必须满足的条件health=true,enable=true and weight>0
func (this *Nacos) Naming_SelectOneHealthyInstance(param vo.SelectOneHealthInstanceParam) (instance *model.Instance, err error) {
instance, err = this.namingClient.SelectOneHealthyInstance(param)
return
}
/// Subscribe key=serviceName+groupName+cluster 注意:我们可以在相同的key添加多个SubscribeCallback.
func (this *Nacos) Naming_Subscribe(param *vo.SubscribeParam) (err error) {
err = this.namingClient.Subscribe(param)
return
}
func (this *Nacos) Naming_Unsubscribe(param *vo.SubscribeParam) (err error) {
err = this.namingClient.Unsubscribe(param)
return
}
func (this *Nacos) Naming_GetAllServicesInfo(param vo.GetAllServiceInfoParam) (serviceInfos model.ServiceList, err error) {
serviceInfos, err = this.namingClient.GetAllServicesInfo(param)
return
}
func (this *Nacos) Config_GetConfig(param vo.ConfigParam) (string, error) {
return this.configClient.GetConfig(param)
}
func (this *Nacos) Config_PublishConfig(param vo.ConfigParam) (bool, error) {
return this.configClient.PublishConfig(param)
}
func (this *Nacos) Config_DeleteConfig(param vo.ConfigParam) (bool, error) {
return this.configClient.PublishConfig(param)
}
func (this *Nacos) Config_ListenConfig(params vo.ConfigParam) (err error) {
return this.configClient.ListenConfig(params)
}
func (this *Nacos) Config_CancelListenConfig(params vo.ConfigParam) (err error) {
return this.configClient.CancelListenConfig(params)
}
func (this *Nacos) Config_SearchConfig(param vo.SearchConfigParam) (*model.ConfigPage, error) {
return this.configClient.SearchConfig(param)
}
func (this *Nacos) Config_PublishAggr(param vo.ConfigParam) (published bool, err error) {
return this.configClient.PublishAggr(param)
}

View File

@ -1,86 +0,0 @@
package nacos
import (
"go_dreamfactory/lego/utils/mapstructure"
)
type NacosClientType uint8
const (
NamingClient NacosClientType = iota
ConfigClient
All
)
type Option func(*Options)
type Options struct {
NacosClientType NacosClientType
NamespaceId string
NacosAddr string
Port uint64
Username string
Password string
TimeoutMs uint64
}
func SetNacosClientType(v NacosClientType) Option {
return func(o *Options) {
o.NacosClientType = v
}
}
func SetNamespaceId(v string) Option {
return func(o *Options) {
o.NamespaceId = v
}
}
func SetNacosAddr(v string) Option {
return func(o *Options) {
o.NacosAddr = v
}
}
func SetPort(v uint64) Option {
return func(o *Options) {
o.Port = v
}
}
func SetUsername(v string) Option {
return func(o *Options) {
o.Username = v
}
}
func SetPassword(v string) Option {
return func(o *Options) {
o.Password = v
}
}
func SetTimeoutMs(v uint64) Option {
return func(o *Options) {
o.TimeoutMs = v
}
}
func newOptions(config map[string]interface{}, opts ...Option) Options {
options := Options{
TimeoutMs: 5000,
}
if config != nil {
mapstructure.Decode(config, &options)
}
for _, o := range opts {
o(&options)
}
return options
}
func newOptionsByOption(opts ...Option) Options {
options := Options{
TimeoutMs: 5000,
}
for _, o := range opts {
o(&options)
}
return options
}

View File

@ -1,43 +0,0 @@
package nacos_test
import (
"fmt"
"testing"
"go_dreamfactory/lego/sys/nacos"
"github.com/nacos-group/nacos-sdk-go/vo"
)
func Test_SysInit(t *testing.T) {
sys, err := nacos.NewSys(
nacos.SetNacosAddr("127.0.0.1"),
nacos.SetPort(8848),
nacos.SetNamespaceId("17d02ef9-afaa-4878-ad6c-9fd697f3b628"),
)
if err != nil {
fmt.Printf("启动系统错误err:%v", err)
}
succ, err := sys.Naming_RegisterInstance(vo.RegisterInstanceParam{
Ip: "127.0.0.1",
Port: 8848,
Weight: 0.69,
GroupName: "demo",
ClusterName: "demo",
ServiceName: "demo1",
Metadata: map[string]string{
"tag": "demo",
},
})
fmt.Printf("sys RegisterInstance succ:%v err:%v", succ, err)
// time.Sleep(time.Second * 3)
serviceInfos, err := sys.Naming_GetAllServicesInfo(vo.GetAllServiceInfoParam{
NameSpace: "17d02ef9-afaa-4878-ad6c-9fd697f3b628",
GroupName: "demo",
})
fmt.Printf("sys GetAllServicesInfo serviceInfos:%+v err:%v", serviceInfos, err)
// succ, err = sys.DeregisterInstance()
// fmt.Printf("sys DeregisterInstance succ:%v err:%v", succ, err)
}

View File

@ -5,9 +5,9 @@ import (
"fmt"
"time"
"go_dreamfactory/lego/sys/codec"
"go_dreamfactory/lego/sys/redis/cluster"
"go_dreamfactory/lego/sys/redis/single"
"go_dreamfactory/lego/utils/codec/json"
"github.com/go-redis/redis/v8"
)
@ -378,41 +378,41 @@ func (this *Redis) Marshal(v interface{}) ([]byte, error) {
if this.options.Codec != nil {
return this.options.Codec.Marshal(v)
} else {
return codec.MarshalJson(v)
return json.Marshal(v)
}
}
func (this *Redis) Unmarshal(data []byte, v interface{}) error {
if this.options.Codec != nil {
return this.options.Codec.Unmarshal(data, v)
} else {
return codec.UnmarshalJson(data, v)
return json.Unmarshal(data, v)
}
}
func (this *Redis) MarshalMap(val interface{}) (ret map[string]string, err error) {
if this.options.Codec != nil {
return this.options.Codec.MarshalMap(val)
} else {
return codec.MarshalMapJson(val)
return json.MarshalMap(val)
}
}
func (this *Redis) UnmarshalMap(data map[string]string, val interface{}) (err error) {
if this.options.Codec != nil {
return this.options.Codec.UnmarshalMap(data, val)
} else {
return codec.UnmarshalMapJson(data, val)
return json.UnmarshalMap(data, val)
}
}
func (this *Redis) MarshalSlice(val interface{}) (ret []string, err error) {
if this.options.Codec != nil {
return this.options.Codec.MarshalSlice(val)
} else {
return codec.MarshalSliceJson(val)
return json.MarshalSlice(val)
}
}
func (this *Redis) UnmarshalSlice(data []string, val interface{}) (err error) {
if this.options.Codec != nil {
return this.options.Codec.UnmarshalSlice(data, val)
} else {
return codec.UnmarshalSliceJson(data, val)
return json.UnmarshalSlice(data, val)
}
}

View File

@ -1,391 +0,0 @@
package registry
import (
"fmt"
"strconv"
"sync"
"time"
hash "github.com/mitchellh/hashstructure"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/log"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/api/watch"
)
func newConsul(options Options) (sys *Consul_Registry, err error) {
sys = &Consul_Registry{
options: options,
}
config := api.DefaultConfig()
if len(options.Consul_Addr) > 0 {
config.Address = options.Consul_Addr
}
if sys.client, err = api.NewClient(config); err != nil {
return nil, err
}
if sys.snodeWP, err = watch.Parse(map[string]interface{}{"type": "services"}); err != nil {
return nil, err
}
sys.snodeWP.Handler = sys.shandler
sys.options.Consul_Addr = config.Address
sys.shash = make(map[string]uint64)
sys.services = make(map[string]*ServiceNode)
sys.rpcsubs = make(map[core.Rpc_Key][]*ServiceNode)
sys.watchers = make(map[string]*watch.Plan)
sys.closeSig = make(chan bool)
sys.isstart = false
return
}
type Consul_Registry struct {
options Options
client *api.Client
snodeWP *watch.Plan
isstart bool
closeSig chan bool
shash map[string]uint64
slock sync.RWMutex
services map[string]*ServiceNode
rlock sync.RWMutex
rpcsubs map[core.Rpc_Key][]*ServiceNode
watchers map[string]*watch.Plan
}
func (this *Consul_Registry) Start() (err error) {
if err = this.getServices(); err != nil {
return
}
if err = this.registerSNode(&ServiceNode{
Tag: this.options.Service.GetTag(),
Id: this.options.Service.GetId(),
IP: this.options.Service.GetIp(),
Port: this.options.Service.GetPort(),
Type: this.options.Service.GetType(),
Category: this.options.Service.GetCategory(),
Version: this.options.Service.GetVersion(),
RpcId: this.options.Service.GetRpcId(),
PreWeight: this.options.Service.GetPreWeight(),
}); err != nil {
return
}
go this.snodeWP.Run(this.options.Consul_Addr)
go this.run()
this.isstart = true
return
}
func (this *Consul_Registry) Stop() (err error) {
this.closeSig <- true
this.isstart = false
this.snodeWP.Stop()
this.deregisterSNode()
return
}
func (this *Consul_Registry) PushServiceInfo() (err error) {
if this.isstart {
err = this.registerSNode(&ServiceNode{
Tag: this.options.Service.GetTag(),
Id: this.options.Service.GetId(),
IP: this.options.Service.GetIp(),
Port: this.options.Service.GetPort(),
Type: this.options.Service.GetType(),
Category: this.options.Service.GetCategory(),
Version: this.options.Service.GetVersion(),
RpcId: this.options.Service.GetRpcId(),
PreWeight: this.options.Service.GetPreWeight(),
})
}
return
}
func (this *Consul_Registry) GetServiceById(sId string) (n *ServiceNode, err error) {
this.slock.RLock()
n, ok := this.services[sId]
this.slock.RUnlock()
if !ok {
return nil, fmt.Errorf("No Found %s", sId)
}
return
}
func (this *Consul_Registry) GetServiceByType(sType string) (n []*ServiceNode) {
this.slock.RLock()
defer this.slock.RUnlock()
n = make([]*ServiceNode, 0)
for _, v := range this.services {
if v.Type == sType {
n = append(n, v)
}
}
return
}
func (this *Consul_Registry) GetAllServices() (n []*ServiceNode) {
this.slock.RLock()
defer this.slock.RUnlock()
n = make([]*ServiceNode, 0)
for _, v := range this.services {
n = append(n, v)
}
return
}
func (this *Consul_Registry) GetServiceByCategory(category core.S_Category) (n []*ServiceNode) {
this.slock.RLock()
defer this.slock.RUnlock()
n = make([]*ServiceNode, 0)
for _, v := range this.services {
if v.Category == category {
n = append(n, v)
}
}
return
}
func (this *Consul_Registry) GetRpcSubById(rId core.Rpc_Key) (n []*ServiceNode) {
n = make([]*ServiceNode, 0)
this.rlock.RLock()
d, ok := this.rpcsubs[rId]
this.rlock.RUnlock()
if ok {
n = d
}
return
}
//内部函数-------------------------------------------------------------------------------------------------------------------------
func (this *Consul_Registry) run() {
t := time.NewTicker(time.Duration(this.options.Consul_RegisterInterval) * time.Second)
locp:
for {
select {
case <-t.C:
err := this.PushServiceInfo()
if err != nil {
log.Warnf("service run Server.Register error: ", err)
}
case <-this.closeSig:
break locp
}
}
log.Infof("Sys Registry is succ exit")
}
func (this *Consul_Registry) getServices() (err error) {
services, err := this.client.Agent().Services()
if err == nil {
for _, v := range services {
if v.Tags[0] == this.options.Service.GetTag() { //自能读取相同标签的服务
this.addandupdataServiceNode(v)
}
}
}
return err
}
func (this *Consul_Registry) registerSNode(snode *ServiceNode) (err error) {
h, err := hash.Hash(snode, nil)
if err != nil {
return err
}
if v, ok := this.shash[snode.Id]; ok && v != 0 && v == h {
if err := this.client.Agent().PassTTL("service:"+snode.Id, ""); err == nil {
return nil
}
}
deregTTL := this.getDeregisterTTL(time.Second * time.Duration(this.options.Consul_RegisterTTL))
check := &api.AgentServiceCheck{
TTL: fmt.Sprintf("%v", time.Second*time.Duration(this.options.Consul_RegisterTTL)),
DeregisterCriticalServiceAfter: fmt.Sprintf("%v", deregTTL),
}
asr := &api.AgentServiceRegistration{
ID: snode.Id,
Name: snode.Type,
Tags: []string{this.options.Service.GetTag()},
Check: check,
Meta: map[string]string{
"tag": snode.Tag,
"ip": snode.IP,
"port": fmt.Sprintf("%d", snode.Port),
"category": string(snode.Category),
"version": snode.Version,
"rpcid": snode.RpcId,
"preweight": fmt.Sprintf("%f", snode.PreWeight),
},
}
if err := this.client.Agent().ServiceRegister(asr); err != nil {
return err
}
return this.client.Agent().PassTTL("service:"+snode.Id, "")
}
func (this *Consul_Registry) deregisterSNode() (err error) {
return this.client.Agent().ServiceDeregister(this.options.Service.GetId())
}
func (this *Consul_Registry) addandupdataServiceNode(as *api.AgentService) (sn *ServiceNode, err error) {
tag := as.Meta["tag"]
ip := as.Meta["ip"]
port, err := strconv.ParseInt(as.Meta["port"], 10, 64)
if err != nil {
log.Errorf("port 读取服务节点异常:%s err:%v", as.Meta["port"], err)
return
}
category := as.Meta["category"]
version := as.Meta["version"]
rpcid := as.Meta["rpcid"]
preweight, err := strconv.ParseFloat(as.Meta["preweight"], 64)
if err != nil {
log.Errorf("registry 读取服务节点异常:%s err:%v", as.Meta["preweight"], err)
return
}
snode := &ServiceNode{
Tag: tag,
Type: as.Service,
Category: core.S_Category(category),
Id: as.ID,
IP: ip,
Port: int(port),
Version: version,
RpcId: rpcid,
PreWeight: preweight,
}
if h, err := hash.Hash(snode, nil); err == nil {
_, ok := this.services[snode.Id]
if !ok {
log.Infof("发现新的服务【%s:%s】", snode.Id, snode.Version)
this.rlock.Lock()
this.services[snode.Id] = snode
this.shash[snode.Id] = h
this.rlock.Unlock()
if this.options.Listener != nil { //异步通知
go this.options.Listener.FindServiceHandlefunc(*snode)
}
} else {
this.rlock.RLock()
v, ok := this.shash[snode.Id]
this.rlock.RUnlock()
if !ok || v != h { //校验不一致
// log.Debugf("更新服务【%s】", snode.Id)
this.rlock.Lock()
this.services[snode.Id] = snode
this.shash[snode.Id] = h
this.rlock.Unlock()
if this.options.Listener != nil { //异步通知
go this.options.Listener.UpDataServiceHandlefunc(*snode)
}
}
}
} else {
log.Errorf("registry 校验服务 hash 值异常:%s", err.Error())
}
return
}
func (this *Consul_Registry) removeServiceNode(sId string) {
this.rlock.RLock()
_, ok := this.services[sId]
this.rlock.RUnlock()
if !ok {
return
}
log.Infof("丢失服务【%s】", sId)
this.rlock.Lock()
delete(this.shash, sId)
delete(this.services, sId)
this.rlock.Unlock()
if this.options.Listener != nil { //异步通知
go this.options.Listener.LoseServiceHandlefunc(sId)
}
}
func (this *Consul_Registry) shandler(idx uint64, data interface{}) {
services, ok := data.(map[string][]string)
if !ok {
return
}
for k, v := range services {
if len(v) > 0 {
if v[0] == this.options.Service.GetTag() {
_, ok := this.watchers[k]
if ok {
continue
}
wp, err := watch.Parse(map[string]interface{}{
"type": "service",
"service": k,
})
if err == nil {
wp.Handler = this.snodehandler
go wp.Run(this.options.Consul_Addr)
this.watchers[k] = wp
}
}
}
}
temp := make(map[string]*ServiceNode)
this.rlock.RLock()
for k, v := range this.services {
temp[k] = v
}
this.rlock.RUnlock()
for k, v := range this.watchers {
if _, ok := services[k]; !ok { //不存在了
v.Stop()
delete(this.watchers, k)
for k1, v1 := range temp {
if v1.Type == k {
this.removeServiceNode(k1)
}
}
}
}
}
func (this *Consul_Registry) snodehandler(idx uint64, data interface{}) {
entries, ok := data.([]*api.ServiceEntry)
if !ok {
return
}
stype := ""
serviceMap := map[string]struct{}{}
for _, v := range entries {
isdele := false
for _, check := range v.Checks {
if check.Status == "critical" {
this.removeServiceNode(v.Service.ID)
isdele = true
break
}
}
if !isdele {
this.addandupdataServiceNode(v.Service)
stype = v.Service.Service
serviceMap[v.Service.ID] = struct{}{}
}
}
temp := make(map[string]*ServiceNode)
this.rlock.RLock()
for k, v := range this.services {
temp[k] = v
}
this.rlock.RUnlock()
for _, v := range temp {
if v.Type == stype {
if _, ok := serviceMap[v.Id]; !ok {
this.removeServiceNode(v.Id)
}
}
}
}
func (this *Consul_Registry) getDeregisterTTL(t time.Duration) time.Duration {
// splay slightly for the watcher?
splay := time.Second * 5
deregTTL := t + splay
// consul has a minimum timeout on deregistration of 1 minute.
if t < time.Minute {
deregTTL = time.Minute + splay
}
return deregTTL
}

View File

@ -1,81 +0,0 @@
package registry
import "go_dreamfactory/lego/core"
type (
IListener interface {
FindServiceHandlefunc(snode ServiceNode)
UpDataServiceHandlefunc(snode ServiceNode)
LoseServiceHandlefunc(sId string)
}
ServiceNode struct {
Tag string `json:"Tag"` //服务集群标签
Type string `json:"Type"` //服务类型
Category core.S_Category `json:"Category"` //服务列别
Id string `json:"Id"` //服务Id
Version string `json:"Version"` //服务版本
IP string `json:"Ip"` //服务Ip
Port int `json:"Port"` //端口
RpcId string `json:"RpcId"` //服务通信Id
PreWeight float64 `json:"PreWeight"` //服务负载权重
}
ISys interface {
Start() error
Stop() error
PushServiceInfo() (err error)
GetServiceById(sId string) (n *ServiceNode, err error)
GetServiceByType(sType string) (n []*ServiceNode)
GetAllServices() (n []*ServiceNode)
GetServiceByCategory(category core.S_Category) (n []*ServiceNode)
GetRpcSubById(rId core.Rpc_Key) (n []*ServiceNode)
}
)
var (
defsys ISys
)
func OnInit(config map[string]interface{}, option ...Option) (err error) {
defsys, err = newSys(newOptions(config, option...))
return
}
func NewSys(option ...Option) (sys ISys, err error) {
sys, err = newSys(newOptionsByOption(option...))
return
}
func Start() error {
return defsys.Start()
}
func Stop() error {
return defsys.Stop()
}
func PushServiceInfo() (err error) {
return defsys.PushServiceInfo()
}
func GetServiceById(sId string) (n *ServiceNode, err error) {
return defsys.GetServiceById(sId)
}
func GetServiceByType(sType string) (n []*ServiceNode) {
return defsys.GetServiceByType(sType)
}
func GetAllServices() (n []*ServiceNode) {
return defsys.GetAllServices()
}
func GetServiceByCategory(category core.S_Category) (n []*ServiceNode) {
return defsys.GetServiceByCategory(category)
}
func GetRpcSubById(rId core.Rpc_Key) (n []*ServiceNode) {
return defsys.GetRpcSubById(rId)
}
func SubscribeRpc(rpc core.Rpc_Key) {
}

View File

@ -1,413 +0,0 @@
package registry
import (
"context"
"fmt"
"sync"
"time"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/log"
hash "github.com/mitchellh/hashstructure"
"github.com/nacos-group/nacos-sdk-go/clients"
"github.com/nacos-group/nacos-sdk-go/clients/naming_client"
"github.com/nacos-group/nacos-sdk-go/common/constant"
"github.com/nacos-group/nacos-sdk-go/model"
"github.com/nacos-group/nacos-sdk-go/vo"
)
func newNacos(options Options) (sys *Nacos_Registry, err error) {
ctx, cancel := context.WithCancel(context.TODO())
sys = &Nacos_Registry{
options: options,
ctx: ctx,
cancel: cancel,
shash: make(map[string]uint64),
services: make(map[string]*ServiceNode),
subscribe: make(map[string]*vo.SubscribeParam),
rpcsubs: make(map[core.Rpc_Key][]*ServiceNode),
}
// 创建clientConfig
clientConfig := constant.ClientConfig{
NamespaceId: options.Nacos_NamespaceId,
TimeoutMs: options.Nacos_TimeoutMs,
BeatInterval: options.Nacos_BeatInterval,
Username: options.Nacos_UserName,
Password: options.Nacos_Password,
NotLoadCacheAtStart: true,
UpdateCacheWhenEmpty: true,
LogDir: "nacos/log",
CacheDir: "nacos/cache",
RotateTime: "1h",
MaxAge: 3,
LogLevel: "error",
}
// 至少一个ServerConfig
serverConfigs := []constant.ServerConfig{
{
IpAddr: options.Nacos_NacosAddr,
ContextPath: "/nacos",
Port: options.Nacos_Port,
Scheme: "http",
},
}
// 创建服务发现客户端的另一种方式 (推荐)
sys.client, err = clients.NewNamingClient(
vo.NacosClientParam{
ClientConfig: &clientConfig,
ServerConfigs: serverConfigs,
},
)
return
}
type Nacos_Registry struct {
options Options
client naming_client.INamingClient
isstart bool
ctx context.Context
cancel context.CancelFunc
slock sync.RWMutex
shash map[string]uint64
subscribe map[string]*vo.SubscribeParam
services map[string]*ServiceNode
rlock sync.RWMutex
rpcsubs map[core.Rpc_Key][]*ServiceNode
}
func (this *Nacos_Registry) Start() (err error) {
if err = this.getServices(); err != nil && err.Error() != "instance list is empty!" {
return
}
if err = this.registerSNode(&ServiceNode{
Tag: this.options.Service.GetTag(),
Id: this.options.Service.GetId(),
IP: this.options.Service.GetIp(),
Port: this.options.Service.GetPort(),
Type: this.options.Service.GetType(),
Category: this.options.Service.GetCategory(),
Version: this.options.Service.GetVersion(),
RpcId: this.options.Service.GetRpcId(),
PreWeight: this.options.Service.GetPreWeight(),
}); err != nil {
return
}
ctx1, _ := context.WithCancel(this.ctx)
go this.run(ctx1)
ctx2, _ := context.WithCancel(this.ctx)
go this.listener(ctx2)
this.isstart = true
return
}
func (this *Nacos_Registry) Stop() (err error) {
this.cancel()
this.isstart = false
return
}
func (this *Nacos_Registry) PushServiceInfo() (err error) {
if this.isstart {
err = this.registerSNode(&ServiceNode{
Tag: this.options.Service.GetTag(),
Id: this.options.Service.GetId(),
IP: this.options.Service.GetIp(),
Port: this.options.Service.GetPort(),
Type: this.options.Service.GetType(),
Category: this.options.Service.GetCategory(),
Version: this.options.Service.GetVersion(),
RpcId: this.options.Service.GetRpcId(),
PreWeight: this.options.Service.GetPreWeight(),
})
}
return
}
func (this *Nacos_Registry) GetServiceById(sId string) (n *ServiceNode, err error) {
this.slock.RLock()
n, ok := this.services[sId]
this.slock.RUnlock()
if !ok {
return nil, fmt.Errorf("No Found %s", sId)
}
return
}
func (this *Nacos_Registry) GetServiceByType(sType string) (n []*ServiceNode) {
this.slock.RLock()
defer this.slock.RUnlock()
n = make([]*ServiceNode, 0)
for _, v := range this.services {
if v.Type == sType {
n = append(n, v)
}
}
return
}
func (this *Nacos_Registry) GetAllServices() (n []*ServiceNode) {
this.slock.RLock()
defer this.slock.RUnlock()
n = make([]*ServiceNode, 0)
for _, v := range this.services {
n = append(n, v)
}
return
}
func (this *Nacos_Registry) GetServiceByCategory(category core.S_Category) (n []*ServiceNode) {
this.slock.RLock()
defer this.slock.RUnlock()
n = make([]*ServiceNode, 0)
for _, v := range this.services {
if v.Category == category {
n = append(n, v)
}
}
return
}
func (this *Nacos_Registry) GetRpcSubById(rId core.Rpc_Key) (n []*ServiceNode) {
n = make([]*ServiceNode, 0)
this.rlock.RLock()
d, ok := this.rpcsubs[rId]
this.rlock.RUnlock()
if ok {
n = d
}
return
}
//内部函数-------------------------------------------------------------------------------------------------------------------------
func (this *Nacos_Registry) run(ctx context.Context) {
t := time.NewTicker(time.Duration(this.options.Consul_RegisterInterval) * time.Second)
defer t.Stop()
locp:
for {
select {
case <-t.C:
err := this.PushServiceInfo()
if err != nil {
log.Warnf("service run Server.Register error: %v", err)
}
case <-ctx.Done():
break locp
}
}
log.Infof("Sys Registry is succ exit run")
}
func (this *Nacos_Registry) listener(ctx context.Context) {
var (
slist model.ServiceList
instances []model.Instance
err error
)
t := time.NewTicker(time.Duration(this.options.Nacos_RegisterTTL) * time.Second)
defer t.Stop()
locp:
for {
select {
case <-t.C:
if slist, err = this.client.GetAllServicesInfo(vo.GetAllServiceInfoParam{
NameSpace: this.options.Nacos_NamespaceId,
GroupName: this.options.Service.GetTag(),
PageNo: 1,
PageSize: 100,
}); err == nil {
var service = make(map[string]struct{})
for _, v := range slist.Doms {
if instances, err = this.client.SelectInstances(vo.SelectInstancesParam{
ServiceName: v,
GroupName: this.options.Service.GetTag(),
HealthyOnly: true,
}); err == nil {
for _, v1 := range instances {
if v1.Enable && v1.Healthy {
service[v] = struct{}{}
this.addandupdataServiceNode(v1)
}
}
}
}
temp := make(map[string]*ServiceNode)
this.rlock.RLock()
for k, v := range this.services {
temp[k] = v
}
this.rlock.RUnlock()
for k, v := range temp {
if _, ok := service[k]; !ok { //不存在了 移除
this.removeServiceNode(v.Id)
}
}
}
case <-ctx.Done():
break locp
}
}
log.Infof("Sys Registry is succ exit listener")
}
func (this *Nacos_Registry) getServices() (err error) {
var (
slist model.ServiceList
instances []model.Instance
)
if slist, err = this.client.GetAllServicesInfo(vo.GetAllServiceInfoParam{
NameSpace: this.options.Nacos_NamespaceId,
GroupName: this.options.Service.GetTag(),
PageNo: 1,
PageSize: 20,
}); err == nil {
for _, v := range slist.Doms {
this.rlock.RLock()
_, ok := this.services[v]
this.rlock.RUnlock()
if !ok {
if instances, err = this.client.SelectInstances(vo.SelectInstancesParam{
ServiceName: v,
GroupName: this.options.Service.GetTag(),
HealthyOnly: true,
}); err == nil {
for _, v1 := range instances {
if v1.Enable && v1.Healthy {
this.addandupdataServiceNode(v1)
}
}
}
}
}
}
return err
}
func (this *Nacos_Registry) registerSNode(snode *ServiceNode) (err error) {
h, err := hash.Hash(snode, nil)
if err != nil {
return err
}
if v, ok := this.shash[snode.Id]; ok && v != 0 && v == h { //没变化不用注册
return
}
var (
// success bool
)
this.deregisterSNode()
_, err = this.client.RegisterInstance(vo.RegisterInstanceParam{
Ip: snode.IP,
Port: uint64(snode.Port),
Weight: snode.PreWeight,
GroupName: snode.Tag,
ServiceName: snode.Id,
Enable: true,
Healthy: true,
Ephemeral: true,
Metadata: map[string]string{
"id": snode.Id,
"tag": snode.Tag,
"type": string(snode.Type),
"category": string(snode.Category),
"version": fmt.Sprintf("%v", snode.Version),
"rpcid": snode.RpcId,
},
})
return
}
func (this *Nacos_Registry) deregisterSNode() (err error) {
_, err = this.client.DeregisterInstance(vo.DeregisterInstanceParam{
Ip: this.options.Service.GetIp(),
Port: 8848,
ServiceName: this.options.Service.GetId(),
GroupName: this.options.Service.GetTag(),
})
return
}
func (this *Nacos_Registry) addandupdataServiceNode(as model.Instance) (sn *ServiceNode, err error) {
var (
version string
rpcid string
snode *ServiceNode
h uint64
)
version = as.Metadata["version"]
rpcid = as.Metadata["rpcid"]
snode = &ServiceNode{
Tag: as.Metadata["tag"],
Type: as.Metadata["type"],
Category: core.S_Category(as.Metadata["category"]),
Id: as.Metadata["id"],
IP: as.Ip,
Port: int(as.Port),
Version: version,
RpcId: rpcid,
PreWeight: as.Weight,
}
if h, err = hash.Hash(snode, nil); err == nil {
_, ok := this.services[snode.Id]
if !ok {
log.Infof("发现新的服务【%s:%s】", snode.Id, snode.Version)
sub := &vo.SubscribeParam{
ServiceName: snode.Id,
GroupName: snode.Tag,
SubscribeCallback: this.subscribecallback,
}
this.rlock.Lock()
this.services[snode.Id] = snode
this.shash[snode.Id] = h
this.subscribe[snode.Id] = sub
this.rlock.Unlock()
if this.options.Listener != nil { //异步通知
go this.options.Listener.FindServiceHandlefunc(*snode)
}
err = this.client.Subscribe(sub)
} else {
this.rlock.RLock()
v, ok := this.shash[snode.Id]
this.rlock.RUnlock()
if !ok || v != h { //校验不一致
// log.Debugf("更新服务【%s】", snode.Id)
this.rlock.Lock()
this.services[snode.Id] = snode
this.shash[snode.Id] = h
this.rlock.Unlock()
if this.options.Listener != nil { //异步通知
go this.options.Listener.UpDataServiceHandlefunc(*snode)
}
}
}
} else {
log.Errorf("registry 校验服务 hash 值异常:%s", err.Error())
}
return
}
func (this *Nacos_Registry) removeServiceNode(sId string) {
this.rlock.RLock()
_, ok := this.services[sId]
sub, _ := this.subscribe[sId]
this.rlock.RUnlock()
if !ok {
return
}
log.Infof("丢失服务【%s】", sId)
this.rlock.Lock()
delete(this.services, sId)
delete(this.subscribe, sId)
delete(this.shash, sId)
this.rlock.Unlock()
this.client.Unsubscribe(sub)
if this.options.Listener != nil { //异步通知
go this.options.Listener.LoseServiceHandlefunc(sId)
}
}
func (this *Nacos_Registry) subscribecallback(services []model.SubscribeService, err error) {
for _, v := range services {
// log.Debugf("subscribecallback:%+v", v)
this.addandupdataServiceNode(model.Instance{
Valid: v.Valid,
Enable: v.Enable,
ServiceName: v.ServiceName,
Ip: v.Ip,
Port: v.Port,
Metadata: v.Metadata,
Weight: v.Weight,
})
}
}

View File

@ -1,135 +0,0 @@
package registry
import (
"go_dreamfactory/lego/base"
"go_dreamfactory/lego/utils/mapstructure"
)
type RegistryType uint8
const (
Registry_Consul RegistryType = iota
Registry_Nacos
Registry_Zookeeper
)
type (
Option func(*Options)
Options struct {
RegistryType RegistryType
Service base.IClusterServiceBase
Listener IListener
Consul_Addr string
Consul_RegisterInterval int //定期注册
Consul_RegisterTTL int
Nacos_NamespaceId string
Nacos_NacosAddr string
Nacos_Port uint64
Nacos_UserName string
Nacos_Password string
Nacos_TimeoutMs uint64 //连接超时 ms
Nacos_BeatInterval int64 //心跳间隔 ms
Nacos_RegisterTTL int
}
)
func SetRegistryType(v RegistryType) Option {
return func(o *Options) {
o.RegistryType = v
}
}
func SetService(v base.IClusterServiceBase) Option {
return func(o *Options) {
o.Service = v
}
}
func SetListener(v IListener) Option {
return func(o *Options) {
o.Listener = v
}
}
func SetConsul_Addr(v string) Option {
return func(o *Options) {
o.Consul_Addr = v
}
}
func SetConsul_RegisterInterval(v int) Option {
return func(o *Options) {
o.Consul_RegisterInterval = v
}
}
func SetConsul_RegisterTTL(v int) Option {
return func(o *Options) {
o.Consul_RegisterTTL = v
}
}
func SetNacos_NamespaceId(v string) Option {
return func(o *Options) {
o.Nacos_NamespaceId = v
}
}
func SetNacos_NacosAddr(v string) Option {
return func(o *Options) {
o.Nacos_NacosAddr = v
}
}
func SetNacos_Port(v uint64) Option {
return func(o *Options) {
o.Nacos_Port = v
}
}
func SetNacos_UserName(v string) Option {
return func(o *Options) {
o.Nacos_UserName = v
}
}
func SetNacos_Password(v string) Option {
return func(o *Options) {
o.Nacos_Password = v
}
}
func SetNacos_TimeoutMs(v uint64) Option {
return func(o *Options) {
o.Nacos_TimeoutMs = v
}
}
func SetNacos_BeatInterval(v int64) Option {
return func(o *Options) {
o.Nacos_BeatInterval = v
}
}
func newOptions(config map[string]interface{}, opts ...Option) Options {
options := Options{
Consul_RegisterInterval: 10,
Consul_RegisterTTL: 15,
Nacos_TimeoutMs: 10000,
Nacos_BeatInterval: 5000,
Nacos_RegisterTTL: 8,
}
if config != nil {
mapstructure.Decode(config, &options)
}
for _, o := range opts {
o(&options)
}
return options
}
func newOptionsByOption(opts ...Option) Options {
options := Options{
Consul_RegisterInterval: 10,
Consul_RegisterTTL: 30,
Nacos_TimeoutMs: 10000,
Nacos_BeatInterval: 5000,
Nacos_RegisterTTL: 8,
}
for _, o := range opts {
o(&options)
}
return options
}

View File

@ -1,10 +0,0 @@
package registry
func newSys(options Options) (sys ISys, err error) {
if options.RegistryType == Registry_Consul {
sys, err = newConsul(options)
} else if options.RegistryType == Registry_Nacos {
sys, err = newNacos(options)
}
return
}

View File

@ -1,117 +0,0 @@
package registry_test
import (
"fmt"
"testing"
"github.com/hashicorp/consul/api"
"github.com/nacos-group/nacos-sdk-go/clients"
"github.com/nacos-group/nacos-sdk-go/common/constant"
"github.com/nacos-group/nacos-sdk-go/vo"
)
func Test_Sys_Nacose(t *testing.T) {
// 创建clientConfig
clientConfig := constant.ClientConfig{
NamespaceId: "ac1b23d5-1c14-4485-9e08-f3cde8c83163",
}
// 至少一个ServerConfig
serverConfigs := []constant.ServerConfig{
{
IpAddr: "172.20.27.126",
ContextPath: "/nacos",
Port: 8888,
Scheme: "http",
},
}
// 创建服务发现客户端的另一种方式 (推荐)
client, err := clients.NewNamingClient(
vo.NacosClientParam{
ClientConfig: &clientConfig,
ServerConfigs: serverConfigs,
},
)
if err != nil {
fmt.Printf("初始化系统失败\n")
}
// if succ, err := client.RegisterInstance(vo.RegisterInstanceParam{
// Ip: "127.0.0.2",
// Port: 8848,
// Weight: 1,
// ServiceName: "test_1",
// Enable: true,
// Healthy: true,
// Ephemeral: true,
// Metadata: map[string]string{
// "type": "test",
// "category": "test",
// "version": fmt.Sprintf("%e", 1.0),
// "rpcid": "rwercsfsdwer",
// "rpcsubscribe": "{}",
// },
// }); err != nil {
// fmt.Printf("RegisterInstance err:%v\n", err)
// } else {
// fmt.Printf("RegisterInstance succ:%v\n", succ)
// }
if slist, err := client.GetAllServicesInfo(vo.GetAllServiceInfoParam{
NameSpace: "ac1b23d5-1c14-4485-9e08-f3cde8c83163",
GroupName: "datacollector",
PageNo: 1,
PageSize: 20,
}); err != nil {
fmt.Printf("GetAllServicesInfo err:%v\n", err)
} else {
fmt.Printf("GetAllServicesInfo :%+v\n", slist)
for _, v := range slist.Doms {
if instances, err := client.SelectInstances(vo.SelectInstancesParam{
ServiceName: v,
GroupName: "datacollector",
HealthyOnly: true,
}); err == nil {
fmt.Printf("instances :%+v\n", instances)
} else {
fmt.Printf("instances err:%v\n", err)
}
// if services, err := client.SelectInstances(vo.SelectInstancesParam{
// ServiceName: v,
// HealthyOnly: true,
// }); err != nil {
// fmt.Printf("SelectInstances err:%v\n", err)
// } else {
// fmt.Printf("SelectInstances :%+v\n", services)
// }
// if services, err := client.SelectAllInstances(vo.SelectAllInstancesParam{
// ServiceName: v,
// }); err != nil {
// fmt.Printf("SelectAllInstances err:%v\n", err)
// } else {
// fmt.Printf("SelectAllInstances :%+v\n", services)
// }
}
}
}
func Test_Sys_Consul(t *testing.T) {
config := api.DefaultConfig()
config.Address = "172.20.27.145:10003"
if client, err := api.NewClient(config); err != nil {
fmt.Printf("NewClient Err:%v\n", err)
return
} else {
if err := client.Agent().ServiceRegister(&api.AgentServiceRegistration{
ID: "test",
Name: "test",
Tags: []string{"test"},
Meta: map[string]string{},
}); err != nil {
fmt.Printf("ServiceRegister Err:%v\n", err)
return
} else {
fmt.Printf("ServiceRegister Succ\n")
}
}
}

View File

@ -1,10 +0,0 @@
package registry
func newZookeeper(options Options) (sys *Zookeeper_Registry, err error) {
return
}
type Zookeeper_Registry struct {
options Options
}

View File

@ -36,6 +36,7 @@ type Client struct {
metadata string
writeTimeout time.Duration
AsyncWrite bool
clusterMu sync.RWMutex
clusterClients map[string]map[string]client.XClient //其他集群客户端
connsMapMu sync.RWMutex
conns map[string]net.Conn
@ -51,15 +52,15 @@ func (this *Client) DoMessage() {
for msg := range this.msgChan {
go func(req *protocol.Message) {
if req.ServicePath != "" && req.ServiceMethod != "" {
this.Debugf("DoMessage :%v", req)
this.options.Log.Debugf("DoMessage :%v", req)
addr, ok := req.Metadata[ServiceAddrKey]
if !ok {
this.Errorf("Metadata no found ServiceAddrKey!")
this.options.Log.Errorf("Metadata no found ServiceAddrKey!")
return
}
conn, ok := this.conns[addr]
if !ok {
this.Errorf("no found conn addr:%s", addr)
this.options.Log.Errorf("no found conn addr:%s", addr)
return
}
res, _ := this.handleRequest(context.Background(), req)
@ -86,6 +87,19 @@ func (this *Client) Stop() (err error) {
return
}
//获取服务集群列表
func (this *Client) GetServiceTags() []string {
this.clusterMu.RLock()
tags := make([]string, len(this.clusterClients))
n := 0
for k, _ := range this.clusterClients {
tags[n] = k
n++
}
this.clusterMu.RUnlock()
return tags
}
//注册Rpc 服务
func (this *Client) RegisterFunction(fn interface{}) (err error) {
_, err = this.registerFunction(this.options.ServiceType, fn, "", false)
@ -247,12 +261,12 @@ func (this *Client) UpdateServer(servers map[string]*ServiceNode) {
ServiceType: this.options.ServiceType,
ServiceAddr: this.options.ServiceAddr},
&ServiceNode{}); err != nil {
this.Errorf("ShakeHands new node addr:%s err:%v", v.ServiceAddr, err)
this.options.Log.Errorf("ShakeHands new node addr:%s err:%v", v.ServiceAddr, err)
this.connectMapMu.Lock()
delete(this.connecting, v.ServiceAddr)
this.connectMapMu.Unlock()
} else {
this.Debugf("UpdateServer addr:%s ", v.ServiceAddr)
this.options.Log.Debugf("UpdateServer addr:%s ", v.ServiceAddr)
}
}
}
@ -265,7 +279,7 @@ func (this *Client) ClientConnected(conn net.Conn) (net.Conn, error) {
this.connsMapMu.Lock()
this.conns[addr] = conn
this.connsMapMu.Unlock()
this.Debugf("ClientConnected addr:%v", addr)
this.options.Log.Debugf("ClientConnected addr:%v", addr)
return conn, nil
}
@ -275,51 +289,10 @@ func (this *Client) ClientConnectionClose(conn net.Conn) error {
this.connsMapMu.Lock()
delete(this.conns, addr)
this.connsMapMu.Unlock()
this.Debugf("ClientConnectionClose addr:%v", addr)
this.options.Log.Debugf("ClientConnectionClose addr:%v", addr)
return nil
}
///日志***********************************************************************
func (this *Client) Debug() bool {
return this.options.Debug
}
func (this *Client) Debugf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Debugf("[SYS RPCX] "+format, a...)
}
}
func (this *Client) Infof(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Infof("[SYS RPCX] "+format, a...)
}
}
func (this *Client) Warnf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Warnf("[SYS RPCX] "+format, a...)
}
}
func (this *Client) Errorf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Errorf("[SYS RPCX] "+format, a...)
}
}
func (this *Client) Panicf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Panicf("[SYS RPCX] "+format, a...)
}
}
func (this *Client) Fatalf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Fatalf("[SYS RPCX] "+format, a...)
}
}
//获取目标客户端
func (this *Client) getclient(ctx *context.Context, clusterTag string, servicePath string) (c client.XClient, err error) {
if servicePath == "" {
@ -392,7 +365,7 @@ func (this *Client) registerFunction(servicePath string, fn interface{}, name st
}
if fname == "" {
errorStr := "rpcx.registerFunction: no func name for type " + f.Type().String()
this.Errorf(errorStr)
this.options.Log.Errorf(errorStr)
return fname, errors.New(errorStr)
}
@ -505,7 +478,7 @@ func (this *Client) handleRequest(ctx context.Context, req *protocol.Message) (r
} else if replyv != nil {
reflectTypePools.Put(mtype.ReplyType, replyv)
}
this.Debugf("server called service %+v for an request %+v", service, req)
this.options.Log.Debugf("server called service %+v for an request %+v", service, req)
return res, nil
}

View File

@ -22,6 +22,7 @@ type (
ISys interface {
Start() (err error)
Stop() (err error)
GetServiceTags() []string
RegisterFunction(fn interface{}) (err error)
RegisterFunctionName(name string, fn interface{}) (err error)
UnregisterAll() (err error)

View File

@ -28,7 +28,7 @@ type Options struct {
AutoConnect bool //自动连接 客户端启动模式下 主动连接发现的节点服务器
SerializeType protocol.SerializeType
Debug bool //日志是否开启
Log log.ILog
Log log.ILogger
}
func SetServiceTag(v string) Option {
@ -79,7 +79,7 @@ func SetDebug(v bool) Option {
o.Debug = v
}
}
func SetLog(v log.ILog) Option {
func SetLog(v log.ILogger) Option {
return func(o *Options) {
o.Log = v
}
@ -100,7 +100,7 @@ func newOptions(config map[string]interface{}, opts ...Option) (options *Options
return options, errors.New("[Sys.RPCX] newOptions err: 启动参数异常")
}
if options.Debug && options.Log == nil {
if options.Log = log.Clone(log.SetLoglayer(2)); options.Log == nil {
if options.Log = log.NewTurnlog(options.Debug, log.Clone("sys.rpc", 2)); options.Log == nil {
err = errors.New("log is nil")
}
}
@ -111,8 +111,6 @@ func newOptionsByOption(opts ...Option) (options *Options, err error) {
options = &Options{
AutoConnect: true,
SerializeType: protocol.MsgPack,
Debug: true,
Log: log.Clone(log.SetLoglayer(2)),
}
for _, o := range opts {
o(options)
@ -121,7 +119,7 @@ func newOptionsByOption(opts ...Option) (options *Options, err error) {
return options, errors.New("[Sys.RPCX] newOptions err: 启动参数异常")
}
if options.Debug && options.Log == nil {
if options.Log = log.Clone(log.SetLoglayer(2)); options.Log == nil {
if options.Log = log.NewTurnlog(options.Debug, log.Clone("sys.rpc", 2)); options.Log == nil {
err = errors.New("log is nil")
}
}

View File

@ -46,6 +46,10 @@ func (this *RPCX) Stop() (err error) {
return
}
//获取服务集群列表
func (this *RPCX) GetServiceTags() []string {
return this.GetServiceTags()
}
func (this *RPCX) RegisterFunction(fn interface{}) (err error) {
this.service.RegisterFunction(fn)
return

View File

@ -63,7 +63,7 @@ type Service struct {
func (this *Service) Start() (err error) {
go func() {
if err = this.server.Serve("tcp", this.options.ServiceAddr); err != nil {
this.Warnf("rpcx server exit:%v", err)
this.options.Log.Warnf("rpcx server exit:%v", err)
}
}()
return
@ -75,6 +75,19 @@ func (this *Service) Stop() (err error) {
return
}
//获取服务集群列表
func (this *Service) GetServiceTags() []string {
this.selectormutex.RLock()
tags := make([]string, len(this.selectors))
n := 0
for k, _ := range this.selectors {
tags[n] = k
n++
}
this.selectormutex.RUnlock()
return tags
}
//注册RPC 服务
func (this *Service) RegisterFunction(fn interface{}) (err error) {
err = this.server.RegisterFunction(this.options.ServiceType, fn, this.metadata)
@ -204,7 +217,7 @@ func (this *Service) PostReadRequest(ctx context.Context, r *protocol.Message, e
ok bool
)
req_metadata := r.Metadata
this.Debugf("PreReadRequest ServicePath:%s ServicePath:%s Metadata:%v ", r.ServicePath, r.ServiceMethod, r.Metadata)
this.options.Log.Debugf("PreReadRequest ServicePath:%s ServicePath:%s Metadata:%v ", r.ServicePath, r.ServiceMethod, r.Metadata)
if stag, ok = req_metadata[ServiceClusterTag]; ok {
this.selectormutex.RLock()
selector, ok = this.selectors[stag]
@ -228,7 +241,7 @@ func (this *Service) PostReadRequest(ctx context.Context, r *protocol.Message, e
}
this.clientmutex.Unlock()
selector.UpdateServer(servers)
this.Debugf("fond new node addr:%s smeta:%s \n", addr, smeta)
this.options.Log.Debugf("fond new node addr:%s smeta:%s \n", addr, smeta)
}
}
}
@ -243,7 +256,7 @@ func (this *Service) PostReadRequest(ctx context.Context, r *protocol.Message, e
this.mutex.Unlock()
switch {
case call == nil:
this.Errorf("callmessage no found call:%d", seq)
this.options.Log.Errorf("callmessage no found call:%d", seq)
case r.MessageStatusType() == protocol.Error:
if len(r.Metadata) > 0 {
call.ResMetadata = r.Metadata
@ -284,42 +297,6 @@ func (this *Service) RpcxShakeHands(ctx context.Context, args *ServiceNode, repl
return nil
}
///日志***********************************************************************
func (this *Service) Debug() bool {
return this.options.Debug
}
func (this *Service) Debugf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Debugf("[SYS RPCX] "+format, a...)
}
}
func (this *Service) Infof(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Infof("[SYS RPCX] "+format, a...)
}
}
func (this *Service) Warnf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Warnf("[SYS RPCX] "+format, a...)
}
}
func (this *Service) Errorf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Errorf("[SYS RPCX] "+format, a...)
}
}
func (this *Service) Panicf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Panicf("[SYS RPCX] "+format, a...)
}
}
func (this *Service) Fatalf(format string, a ...interface{}) {
if this.options.Debug {
this.options.Log.Fatalf("[SYS RPCX] "+format, a...)
}
}
//执行远程调用
func (this *Service) call(ctx context.Context, clusterTag string, servicePath string, serviceMethod string, args interface{}, reply interface{}, done chan *client.Call) (conn net.Conn, _call *client.Call, err error) {
var (

View File

@ -3,29 +3,11 @@ package codec
import (
"encoding/binary"
"math"
"strconv"
"unsafe"
)
const host32bit = ^uint(0)>>32 == 0
type (
IDecoder interface {
Decoder(buf []byte, v interface{}) error
DecoderMap(data map[string][]byte, v interface{}) error
DecoderString(buf string, v interface{}) error
DecoderMapString(data map[string]string, v interface{}) error
DecoderSliceString(data []string, v interface{}) error
}
IEncoder interface {
Encoder(v interface{}) (data []byte, err error)
EncoderToMap(v interface{}) (data map[string][]byte, err error)
EncoderString(v interface{}) (data string, err error)
EncoderToMapString(v interface{}) (data map[string]string, err error)
EncoderToSliceString(v interface{}) (data []string, err error)
}
)
// string
func BytesToString(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
@ -186,31 +168,3 @@ func BytesToBool(buf []byte) bool {
var data bool = buf[0] != 0
return data
}
func Atoi(b []byte) (int, error) {
return strconv.Atoi(BytesToString(b))
}
func ParseInt(b []byte, base int, bitSize int) (int64, error) {
return strconv.ParseInt(BytesToString(b), base, bitSize)
}
func ParseUint(b []byte, base int, bitSize int) (uint64, error) {
return strconv.ParseUint(BytesToString(b), base, bitSize)
}
func ParseFloat(b []byte, bitSize int) (float64, error) {
return strconv.ParseFloat(BytesToString(b), bitSize)
}
func UintToString(n uint64) string {
return BytesToString(strconv.AppendUint([]byte{}, n, 10))
}
func IntToString(n int64) string {
return BytesToString(strconv.AppendInt([]byte{}, n, 10))
}
func FloatToString(f float64) string {
return BytesToString(strconv.AppendFloat([]byte{}, f, 'f', -1, 64))
}

70
lego/utils/codec/codec.go Normal file
View File

@ -0,0 +1,70 @@
package codec
import (
"sync"
"go_dreamfactory/lego/utils/codec/codecore"
"go_dreamfactory/lego/utils/codec/factory"
"github.com/modern-go/reflect2"
)
var decoderCache = new(sync.Map)
var encoderCache = new(sync.Map)
func AddDecoder(cacheKey uintptr, decoder codecore.IDecoder) {
decoderCache.Store(cacheKey, decoder)
}
func AddEncoder(cacheKey uintptr, encoder codecore.IEncoder) {
encoderCache.Store(cacheKey, encoder)
}
func GetEncoder(cacheKey uintptr) codecore.IEncoder {
encoder, found := encoderCache.Load(cacheKey)
if found {
return encoder.(codecore.IEncoder)
}
return nil
}
func GetDecoder(cacheKey uintptr) codecore.IDecoder {
decoder, found := decoderCache.Load(cacheKey)
if found {
return decoder.(codecore.IDecoder)
}
return nil
}
func EncoderOf(typ reflect2.Type, config *codecore.Config) codecore.IEncoder {
cacheKey := typ.RType()
encoder := GetEncoder(cacheKey)
if encoder != nil {
return encoder
}
ctx := &codecore.Ctx{
Config: config,
Prefix: "",
Decoders: map[reflect2.Type]codecore.IDecoder{},
Encoders: map[reflect2.Type]codecore.IEncoder{},
}
encoder = factory.EncoderOfType(ctx, typ)
if typ.LikePtr() {
encoder = factory.NewonePtrEncoder(encoder)
}
AddEncoder(cacheKey, encoder)
return encoder
}
func DecoderOf(typ reflect2.Type, config *codecore.Config) codecore.IDecoder {
cacheKey := typ.RType()
decoder := GetDecoder(cacheKey)
if decoder != nil {
return decoder
}
ctx := &codecore.Ctx{
Config: config,
Prefix: "",
Decoders: map[reflect2.Type]codecore.IDecoder{},
Encoders: map[reflect2.Type]codecore.IEncoder{},
}
ptrType := typ.(*reflect2.UnsafePtrType)
decoder = factory.DecoderOfType(ctx, ptrType.Elem())
AddDecoder(cacheKey, decoder)
return decoder
}

View File

@ -1,65 +1,43 @@
package codec
package codec_test
import (
"encoding/json"
"fmt"
"go_dreamfactory/lego/utils/codec/json"
"testing"
)
type TestData struct {
Fild_1 string
Fild_3 int
Fild_4 float32
Name string
Value int
Array []interface{}
Data map[string]interface{}
}
type Test1Data struct {
Name string
Value int
}
func Test_Encoder(t *testing.T) {
encoder := &Encoder{}
// data, err := encoder.EncoderToMap(map[string]interface{}{"liwei": 106, "sasd": "2564"})
// fmt.Printf("EncoderToMap data1:%v err:%v", data, err)
data, err := encoder.EncoderToMap([]interface{}{"liwei", 106, "sasd", "2564"})
fmt.Printf("EncoderToMap data1:%v err:%v", data, err)
// data, err := encoder.EncoderToMap(&TestData{Fild_1: "liwei1dao", Fild_3: 25, Fild_4: 3.54})
// fmt.Printf("EncoderToMap data2:%v err:%v", data, err)
func Test_sys_slice(t *testing.T) {
data := []*Test1Data{{"liwe", 1}, {"liwe2", 2}}
d, err := json.Marshal(data)
fmt.Printf("codec Marshal d:%s err:%v", d, err)
data = []*Test1Data{}
err = json.Unmarshal(d, &data)
fmt.Printf("codec UnmarshalJson data:%v err:%v", data, err)
}
func Test_Decoder(t *testing.T) {
decoder := &Decoder{}
func Test_sys_json(t *testing.T) {
d, err := json.Marshal(&TestData{Name: "http://liwei1dao.com?asd=1&dd=1", Value: 10, Array: []interface{}{1, "dajiahao", &Test1Data{Name: "liwe1dao", Value: 123}}, Data: map[string]interface{}{"hah": 1, "asd": 999}})
fmt.Printf("codec Marshal d:%s err:%v", d, err)
data := &TestData{}
err := decoder.DecoderMapString(map[string]string{"Fild_1": "liwei1dao"}, data)
fmt.Printf("DecoderMap data1:%v err:%v", data, err)
err = json.Unmarshal(d, data)
fmt.Printf("codec UnmarshalJson data:%v err:%v", data, err)
}
func Test_Slice_Decoder(t *testing.T) {
decoder := &Decoder{DefDecoder: json.Unmarshal}
encoder := &Encoder{DefEncoder: json.Marshal}
data := []*TestData{{Fild_1: "1dao", Fild_3: 10, Fild_4: 3.5}, {Fild_1: "2dao", Fild_3: 20, Fild_4: 6.5}}
datastr, err := encoder.EncoderToSliceString(data)
fmt.Printf("EncoderToSliceString datastr:%v err:%v", datastr, err)
if err != nil {
return
}
data1 := make([]*TestData, 0)
err = decoder.DecoderSliceString(datastr, data1)
fmt.Printf("DecoderMap data1:%v err:%v", data1, err)
}
func Test_sys_mapjson(t *testing.T) {
d, err := json.MarshalMap(&TestData{Name: "http://liwei1dao.com?asd=1&dd=1", Value: 10, Array: []interface{}{1, "dajiahao", &Test1Data{Name: "liwe1dao", Value: 123}}, Data: map[string]interface{}{"hah": 1, "asd": 999}})
fmt.Printf("codec Marshal d:%s err:%v", d, err)
data := &TestData{}
err = json.UnmarshalMap(d, data)
fmt.Printf("codec UnmarshalJson data:%v err:%v", data, err)
func Test_Slice_Type(t *testing.T) {
decoder := &Decoder{DefDecoder: json.Unmarshal}
encoder := &Encoder{DefEncoder: json.Marshal}
data := []*TestData{{Fild_1: "1dao", Fild_3: 10, Fild_4: 3.5}, {Fild_1: "2dao", Fild_3: 20, Fild_4: 6.5}}
datastr, err := encoder.EncoderToSliceString(data)
fmt.Printf("EncoderToSliceString datastr:%v err:%v", datastr, err)
if err != nil {
return
}
data1 := make([]*TestData, 0)
err = decoder.DecoderSliceString(datastr, &data1)
fmt.Printf("DecoderMap data1:%v err:%v", data1, err)
}
func Test_EncoderToMapString(t *testing.T) {
encoder := &Encoder{DefEncoder: json.Marshal}
data := &TestData{Fild_1: "1dao", Fild_3: 10, Fild_4: 3.5}
_map, err := encoder.EncoderToMapString(data)
fmt.Printf("DecoderMap map:%v err:%v", _map, err)
}

View File

@ -1,4 +1,4 @@
package core
package codecore
import (
"reflect"
@ -7,15 +7,6 @@ import (
"github.com/modern-go/reflect2"
)
//数据类型
type CodecType int8
const (
Json CodecType = iota //json 格式数据
Bytes //byte 字节流数据
Proto //proto google protobuff 数据
)
//结构值类型
type ValueType int
@ -37,18 +28,14 @@ const (
)
type (
ICodec interface {
Options() *Options
GetEncoderFromCache(cacheKey uintptr) IEncoder
GetDecoderFromCache(cacheKey uintptr) IDecoder
EncoderOf(typ reflect2.Type) IEncoder
DecoderOf(typ reflect2.Type) IDecoder
BorrowExtractor(buf []byte) IExtractor //借 提取器
ReturnExtractor(extra IExtractor) //还 提取器
BorrowStream() IStream //借 输出对象
ReturnStream(stream IStream) //换 输出对象
IPools interface {
GetReader(buf []byte) IReader
PutReader(w IReader)
GetWriter() IWriter
PutWriter(w IWriter)
}
IExtractor interface {
IReader interface {
IPools
ReadVal(obj interface{}) //读取指定类型对象
WhatIsNext() ValueType
Read() interface{}
@ -80,7 +67,8 @@ type (
Error() error
SetErr(err error)
}
IStream interface {
IWriter interface {
IPools
WriteVal(val interface{}) //写入一个对象
WriteNil() //写空 null
WriteEmptyArray() //写空数组 []
@ -107,42 +95,36 @@ type (
WriteFloat64(val float64)
WriteString(val string)
WriteBytes(val []byte)
Reset(bufSize int)
Reset()
Buffer() []byte //返回缓存区数据
Buffered() int
Error() error
SetErr(err error)
}
//Json 编码器
IEncoder interface {
GetType() reflect.Kind
IsEmpty(ptr unsafe.Pointer) bool
Encode(ptr unsafe.Pointer, stream IStream)
}
//MapJson 编码器
IEncoderMapJson interface {
EncodeToMapJson(ptr unsafe.Pointer) (ret map[string]string, err error)
}
//SliceJson 编码器
IEncoderSliceJson interface {
EncodeToSliceJson(ptr unsafe.Pointer) (ret []string, err error)
}
//Json 解码器
IDecoder interface {
GetType() reflect.Kind
Decode(ptr unsafe.Pointer, extra IExtractor)
Decode(ptr unsafe.Pointer, r IReader)
}
//MapJson 解码器
IDecoderMapJson interface {
DecodeForMapJson(ptr unsafe.Pointer, extra map[string]string) (err error)
DecodeForMapJson(ptr unsafe.Pointer, r IReader, extra map[string]string) (err error)
}
//MapJson 解码器
IDecoderSliceJson interface {
DecodeForSliceJson(ptr unsafe.Pointer, extra []string) (err error)
DecodeForSliceJson(ptr unsafe.Pointer, r IReader, extra []string) (err error)
}
//空校验
CheckIsEmpty interface {
IEncoder interface {
GetType() reflect.Kind
IsEmpty(ptr unsafe.Pointer) bool
Encode(ptr unsafe.Pointer, w IWriter)
}
//MapJson 编码器
IEncoderMapJson interface {
EncodeToMapJson(ptr unsafe.Pointer, w IWriter) (ret map[string]string, err error)
}
//SliceJson 编码器
IEncoderSliceJson interface {
EncodeToSliceJson(ptr unsafe.Pointer, w IWriter) (ret []string, err error)
}
//内嵌指针是否是空
IsEmbeddedPtrNil interface {
@ -150,8 +132,17 @@ type (
}
)
//序列化配置
type Config struct {
SortMapKeys bool //排序mapkey
IndentionStep int //缩进步骤
OnlyTaggedField bool //仅仅处理标签字段
DisallowUnknownFields bool //禁止未知字段
CaseSensitive bool //是否区分大小写
TagKey string //标签
}
type Ctx struct {
ICodec
Config *Config
Prefix string
Encoders map[reflect2.Type]IEncoder
Decoders map[reflect2.Type]IDecoder
@ -159,7 +150,7 @@ type Ctx struct {
func (this *Ctx) Append(prefix string) *Ctx {
return &Ctx{
ICodec: this.ICodec,
Config: this.Config,
Prefix: this.Prefix + " " + prefix,
Encoders: this.Encoders,
Decoders: this.Decoders,

View File

@ -0,0 +1,75 @@
package codec
import (
"bytes"
"compress/gzip"
"io/ioutil"
"sync"
)
var (
spWriter sync.Pool
spReader sync.Pool
spBuffer sync.Pool
)
func init() {
spWriter = sync.Pool{New: func() interface{} {
return gzip.NewWriter(nil)
}}
spReader = sync.Pool{New: func() interface{} {
return new(gzip.Reader)
}}
spBuffer = sync.Pool{New: func() interface{} {
return bytes.NewBuffer(nil)
}}
}
// Unzip unzips data.
func Unzip(data []byte) ([]byte, error) {
buf := bytes.NewBuffer(data)
gr := spReader.Get().(*gzip.Reader)
defer func() {
spReader.Put(gr)
}()
err := gr.Reset(buf)
if err != nil {
return nil, err
}
defer gr.Close()
data, err = ioutil.ReadAll(gr)
if err != nil {
return nil, err
}
return data, err
}
// Zip zips data.
func Zip(data []byte) ([]byte, error) {
buf := spBuffer.Get().(*bytes.Buffer)
w := spWriter.Get().(*gzip.Writer)
w.Reset(buf)
defer func() {
buf.Reset()
spBuffer.Put(buf)
w.Close()
spWriter.Put(w)
}()
_, err := w.Write(data)
if err != nil {
return nil, err
}
err = w.Flush()
if err != nil {
return nil, err
}
err = w.Close()
if err != nil {
return nil, err
}
dec := buf.Bytes()
return dec, nil
}

View File

@ -1,362 +0,0 @@
package codec
import (
"fmt"
"reflect"
"strconv"
"time"
)
//解码器
type Decoder struct {
DefDecoder func(buf []byte, v interface{}) error //默认编码 扩展自定义编码方式
}
func (this *Decoder) Decoder(buf []byte, v interface{}) error {
switch v := v.(type) {
case nil:
return fmt.Errorf("decoder: Decoder(nil)")
case *string:
*v = BytesToString(buf)
return nil
case *[]byte:
*v = buf
return nil
case *int:
*v = BytesToInt(buf)
return nil
case *int8:
*v = BytesToInt8(buf)
return nil
case *int16:
*v = BytesToInt16(buf)
return nil
case *int32:
*v = BytesToInt32(buf)
return nil
case *int64:
*v = BytesToInt64(buf)
return nil
case *uint:
*v = BytesToUInt(buf)
return nil
case *uint8:
*v = BytesToUInt8(buf)
return nil
case *uint16:
*v = BytesToUInt16(buf)
return nil
case *uint32:
*v = BytesToUInt32(buf)
return nil
case *uint64:
*v = BytesToUInt64(buf)
return nil
case *float32:
*v = BytesToFloat32(buf)
return nil
case *float64:
*v = BytesToFloat64(buf)
return nil
case *bool:
*v = BytesToBool(buf)
return nil
case *time.Time:
var err error
*v, err = time.Parse(time.RFC3339Nano, BytesToString(buf))
return err
case *time.Duration:
*v = time.Duration(BytesToInt64(buf))
return nil
default:
if this.DefDecoder != nil {
return this.DefDecoder(buf, v)
} else {
return fmt.Errorf(
"decoder: can't marshal %T (implement decoder.DefDecoder)", v)
}
}
}
func (this *Decoder) DecoderMap(data map[string][]byte, v interface{}) error {
vof := reflect.ValueOf(v)
if !vof.IsValid() {
return fmt.Errorf("Decoder: DecoderMap(nil)")
}
if vof.Kind() != reflect.Ptr && vof.Kind() != reflect.Map && vof.Kind() != reflect.Slice {
return fmt.Errorf("Decoder: DecoderMap(non-pointer %T)", v)
}
if vof.Kind() == reflect.Map {
kt, vt := vof.Type().Key(), vof.Type().Elem()
for k, v := range data {
key := reflect.New(kt).Elem()
if key.Kind() != reflect.Ptr {
if err := this.Decoder(StringToBytes(k), key.Addr().Interface()); err != nil {
return fmt.Errorf("Decoder: Decoder(non-pointer %T) err:%v", key, err)
}
} else {
if err := this.Decoder(StringToBytes(k), key.Addr()); err != nil {
return fmt.Errorf("Decoder: Decoder(non-pointer %T) err:%v", key, err)
}
}
value := reflect.New(vt).Elem()
if value.Kind() != reflect.Ptr {
if err := this.Decoder(v, value.Addr().Interface()); err != nil {
return fmt.Errorf("Decoder: Decoder(non-pointer %T) err:%v", value, err)
}
} else {
value.Interface()
if err := this.Decoder(v, value.Addr().Interface()); err != nil {
return fmt.Errorf("Decoder: Decoder(non-pointer %T) err:%v", value, err)
}
}
vof.SetMapIndex(key, value)
}
} else if vof.Kind() == reflect.Ptr {
elem := vof.Elem()
relType := elem.Type()
for i := 0; i < relType.NumField(); i++ {
fieldInfo := relType.Field(i)
tag := fieldInfo.Tag
name := tag.Get("json")
if len(name) == 0 {
name = fieldInfo.Name
}
if value, ok := data[name]; ok {
v := reflect.New(fieldInfo.Type).Elem()
if fieldInfo.Type.Kind() != reflect.Ptr {
if err := this.Decoder(value, v.Addr().Interface()); err != nil {
return fmt.Errorf("Decoder: Decoder(non-pointer %T) err:%v", value, err)
}
elem.FieldByName(fieldInfo.Name).Set(v)
} else {
if err := this.Decoder(value, v); err != nil {
return fmt.Errorf("Decoder: Decoder(non-pointer %T) err:%v", value, err)
}
elem.FieldByName(fieldInfo.Name).Set(v)
}
}
}
}
return nil
}
//redis 存储解析 针对 string 转换
func (this *Decoder) DecoderString(buf string, v interface{}) (err error) {
switch v := v.(type) {
case nil:
return fmt.Errorf("decoder: Decoder(nil)")
case *string:
*v = buf
return nil
case *[]byte:
*v = StringToBytes(buf)
return nil
case *int:
*v, err = Atoi(StringToBytes(buf))
return
case *int8:
var n int64
n, err = ParseInt(StringToBytes(buf), 10, 8)
if err != nil {
return err
}
*v = int8(n)
return
case *int16:
var n int64
n, err = ParseInt(StringToBytes(buf), 10, 16)
if err != nil {
return err
}
*v = int16(n)
return
case *int32:
var n int64
n, err = ParseInt(StringToBytes(buf), 10, 32)
if err != nil {
return err
}
*v = int32(n)
return
case *int64:
var n int64
n, err = ParseInt(StringToBytes(buf), 10, 64)
if err != nil {
return err
}
*v = n
return
case *uint:
var n uint64
n, err = ParseUint(StringToBytes(buf), 10, 64)
if err != nil {
return err
}
*v = uint(n)
return
case *uint8:
var n uint64
n, err = ParseUint(StringToBytes(buf), 10, 8)
if err != nil {
return err
}
*v = uint8(n)
return
case *uint16:
var n uint64
n, err = ParseUint(StringToBytes(buf), 10, 16)
if err != nil {
return err
}
*v = uint16(n)
return
case *uint32:
var n uint64
n, err = ParseUint(StringToBytes(buf), 10, 32)
if err != nil {
return err
}
*v = uint32(n)
return
case *uint64:
var n uint64
n, err = ParseUint(StringToBytes(buf), 10, 64)
if err != nil {
return err
}
*v = n
return
case *float32:
var f float64
f, err = strconv.ParseFloat(buf, 32)
*v = float32(f)
return
case *float64:
*v, err = strconv.ParseFloat(buf, 64)
return
case *bool:
*v, err = strconv.ParseBool(buf)
return
case *time.Time:
var err error
*v, err = time.Parse(time.RFC3339Nano, buf)
return err
case *time.Duration:
var n int64
n, err = ParseInt(StringToBytes(buf), 10, 64)
if err != nil {
return err
}
*v = time.Duration(n)
return
default:
if this.DefDecoder != nil {
return this.DefDecoder(StringToBytes(buf), v)
} else {
return fmt.Errorf(
"decoder: can't marshal %T (implement decoder.DefDecoder)", v)
}
}
}
//redis 存储解析 针对 string 转换
func (this *Decoder) DecoderMapString(data map[string]string, v interface{}) error {
vof := reflect.ValueOf(v)
if !vof.IsValid() {
return fmt.Errorf("Decoder: DecoderMap(nil)")
}
if vof.Kind() != reflect.Ptr && vof.Kind() != reflect.Map && vof.Kind() != reflect.Slice {
return fmt.Errorf("Decoder: DecoderMap(non-pointer %T)", v)
}
if vof.Kind() == reflect.Map {
kt, vt := vof.Type().Key(), vof.Type().Elem()
for k, v := range data {
key := reflect.New(kt).Elem()
if key.Kind() != reflect.Ptr {
if err := this.DecoderString(k, key.Addr().Interface()); err != nil {
return fmt.Errorf("Decoder: Decoder(non-pointer %T) err:%v", key, err)
}
} else {
if err := this.DecoderString(k, key.Addr()); err != nil {
return fmt.Errorf("Decoder: Decoder(non-pointer %T) err:%v", key, err)
}
}
value := reflect.New(vt).Elem()
if value.Kind() != reflect.Ptr {
if err := this.DecoderString(v, value.Addr().Interface()); err != nil {
return fmt.Errorf("Decoder: Decoder(non-pointer %T) err:%v", value, err)
}
} else {
value.Interface()
if err := this.DecoderString(v, value.Addr().Interface()); err != nil {
return fmt.Errorf("Decoder: Decoder(non-pointer %T) err:%v", value, err)
}
}
vof.SetMapIndex(key, value)
}
} else if vof.Kind() == reflect.Ptr {
elem := vof.Elem()
relType := elem.Type()
for i := 0; i < relType.NumField(); i++ {
fieldInfo := relType.Field(i)
tag := fieldInfo.Tag
name := tag.Get("json")
if len(name) == 0 {
name = fieldInfo.Name
}
if value, ok := data[name]; ok {
v := reflect.New(fieldInfo.Type).Elem()
if err := this.DecoderString(value, v.Addr().Interface()); err != nil {
return fmt.Errorf("Decoder: Decoder(non-pointer %T) err:%v", value, err)
}
elem.FieldByName(fieldInfo.Name).Set(v)
}
}
}
return nil
}
//redis 存储解析 针对 string 转换
func (this *Decoder) DecoderSliceString(data []string, v interface{}) error {
t := reflect.TypeOf(v)
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
if t.Kind() == reflect.Slice {
t = t.Elem()
} else {
panic("Input param is not a slice")
}
sl := reflect.ValueOf(v)
if t.Kind() == reflect.Ptr {
sl = sl.Elem()
}
st := sl.Type()
fmt.Printf("Slice Type %s:\n", st)
sliceType := st.Elem()
if sliceType.Kind() == reflect.Ptr {
sliceType = sliceType.Elem()
}
fmt.Printf("Slice Elem Type %v:\n", sliceType)
for _, buf := range data {
if sl.Len() < sl.Cap() {
sl.Set(sl.Slice(0, sl.Len()+1))
elem := sl.Index(sl.Len() - 1)
if elem.IsNil() {
elem.Set(reflect.New(sliceType))
}
this.DecoderString(buf, elem.Elem().Addr().Interface())
continue
}
elem := reflect.New(sliceType)
sl.Set(reflect.Append(sl, elem))
this.DecoderString(buf, elem.Elem().Addr().Interface())
}
return nil
}

View File

@ -1,260 +0,0 @@
package codec
import (
"fmt"
"reflect"
"time"
)
//编码器
type Encoder struct {
DefEncoder func(v interface{}) (data []byte, err error) //默认编码 扩展自定义编码方式
}
func (this *Encoder) Encoder(v interface{}) (data []byte, err error) {
switch v := v.(type) {
case nil:
return StringToBytes(""), nil
case string:
return StringToBytes(v), nil
case []byte:
return v, nil
case int:
return IntToBytes(v), nil
case int8:
return Int8ToBytes(v), nil
case int16:
return Int16ToBytes(v), nil
case int32:
return Int32ToBytes(v), nil
case int64:
return Int64ToBytes(v), nil
case uint:
return UIntToBytes(v), nil
case uint8:
return UInt8ToBytes(v), nil
case uint16:
return UInt16ToBytes(v), nil
case uint32:
return UInt32ToBytes(v), nil
case uint64:
return UInt64ToBytes(v), nil
case float32:
return Float32ToBytes(v), nil
case float64:
return Float64ToBytes(v), nil
case bool:
return BoolToBytes(v), nil
case time.Time:
return v.AppendFormat([]byte{}, time.RFC3339Nano), nil
case time.Duration:
return Int64ToBytes(v.Nanoseconds()), nil
default:
if this.DefEncoder != nil {
return this.DefEncoder(v)
} else {
return nil, fmt.Errorf(
"encoder: can't marshal %T (implement encoder.DefEncoder)", v)
}
}
}
func (this *Encoder) EncoderToMap(v interface{}) (data map[string][]byte, err error) {
vof := reflect.ValueOf(v)
if !vof.IsValid() {
return nil, fmt.Errorf("Encoder: EncoderToMap(nil)")
}
if vof.Kind() != reflect.Ptr && vof.Kind() != reflect.Map && vof.Kind() != reflect.Slice {
return nil, fmt.Errorf("Encoder: EncoderToMap(non-pointer %T)", v)
}
// vof = vof.Elem()
data = make(map[string][]byte)
if vof.Kind() == reflect.Map {
keys := vof.MapKeys()
for _, k := range keys {
value := vof.MapIndex(k)
var keydata []byte
var valuedata []byte
if keydata, err = this.Encoder(k.Interface()); err != nil {
return nil, fmt.Errorf("Encoder: EncoderToMap(invalid type %T) err:%v", value.Interface(), err)
}
if valuedata, err = this.Encoder(value.Interface()); err != nil {
return nil, fmt.Errorf("Encoder: EncoderToMap(invalid type %T) err:%v", value.Interface(), err)
}
data[BytesToString(keydata)] = valuedata
}
return
} else if vof.Kind() == reflect.Slice {
for i := 0; i < vof.Len(); i++ {
value := vof.Index(i).Interface()
var valuedata []byte
if valuedata, err = this.Encoder(value); err != nil {
return nil, fmt.Errorf("Encoder: EncoderToMap(invalid type %T) err:%v", value, err)
}
data[BytesToString(IntToBytes(i))] = valuedata
}
return
} else if vof.Kind() == reflect.Ptr {
elem := vof.Elem()
relType := elem.Type()
for i := 0; i < relType.NumField(); i++ {
fieldInfo := relType.Field(i)
tag := fieldInfo.Tag
name := tag.Get("json")
if len(name) == 0 {
name = fieldInfo.Name
}
field := elem.Field(i).Interface()
var valuedata []byte
if valuedata, err = this.Encoder(field); err != nil {
return nil, fmt.Errorf("Encoder: EncoderToMap(invalid type %T) err:%v", field, err)
}
data[name] = valuedata
}
return
} else {
return nil, fmt.Errorf("Encoder: EncoderToMap(invalid type %T)", v)
}
}
//redis 存储编码 针对 string 转换
func (this *Encoder) EncoderString(v interface{}) (data string, err error) {
switch v := v.(type) {
case nil:
return "", nil
case string:
return v, nil
case []byte:
return BytesToString(v), nil
case int:
return IntToString(int64(v)), nil
case int8:
return IntToString(int64(v)), nil
case int16:
return IntToString(int64(v)), nil
case int32:
return IntToString(int64(v)), nil
case int64:
return IntToString(int64(v)), nil
case uint:
return UintToString(uint64(v)), nil
case uint8:
return UintToString(uint64(v)), nil
case uint16:
return UintToString(uint64(v)), nil
case uint32:
return UintToString(uint64(v)), nil
case uint64:
return UintToString(uint64(v)), nil
case float32:
return UintToString(uint64(v)), nil
case float64:
return UintToString(uint64(v)), nil
case bool:
if v {
return IntToString(1), nil
}
return IntToString(0), nil
case time.Time:
return BytesToString(v.AppendFormat([]byte{}, time.RFC3339Nano)), nil
case time.Duration:
return IntToString(v.Nanoseconds()), nil
default:
if this.DefEncoder != nil {
var b []byte
b, err = this.DefEncoder(v)
if err != nil {
return "", err
}
return BytesToString(b), nil
} else {
return "", fmt.Errorf(
"encoder: can't marshal %T (implement encoder.DefEncoder)", v)
}
}
}
//redis 存储编码 针对 string 转换
func (this *Encoder) EncoderToMapString(v interface{}) (data map[string]string, err error) {
vof := reflect.ValueOf(v)
if !vof.IsValid() {
return nil, fmt.Errorf("Encoder: EncoderToMap(nil)")
}
if vof.Kind() != reflect.Ptr && vof.Kind() != reflect.Map && vof.Kind() != reflect.Slice {
return nil, fmt.Errorf("Encoder: EncoderToMap(non-pointer %T)", v)
}
// vof = vof.Elem()
data = make(map[string]string)
if vof.Kind() == reflect.Map {
keys := vof.MapKeys()
for _, k := range keys {
value := vof.MapIndex(k)
var keydata string
var valuedata string
if keydata, err = this.EncoderString(k.Interface()); err != nil {
return nil, fmt.Errorf("Encoder: EncoderToMap(invalid type %T) err:%v", value.Interface(), err)
}
if valuedata, err = this.EncoderString(value.Interface()); err != nil {
return nil, fmt.Errorf("Encoder: EncoderToMap(invalid type %T) err:%v", value.Interface(), err)
}
data[keydata] = valuedata
}
return
} else if vof.Kind() == reflect.Slice {
for i := 0; i < vof.Len(); i++ {
value := vof.Index(i).Interface()
var valuedata string
if valuedata, err = this.EncoderString(value); err != nil {
return nil, fmt.Errorf("Encoder: EncoderToMap(invalid type %T) err:%v", value, err)
}
data[IntToString(int64(i))] = valuedata
}
return
} else if vof.Kind() == reflect.Ptr {
elem := vof.Elem()
relType := elem.Type()
for i := 0; i < relType.NumField(); i++ {
fieldInfo := relType.Field(i)
tag := fieldInfo.Tag
name := tag.Get("json")
if len(name) == 0 {
continue
}
field := elem.Field(i).Interface()
var valuedata string
if valuedata, err = this.EncoderString(field); err != nil {
return nil, fmt.Errorf("Encoder: EncoderToMap(invalid type %T) err:%v", field, err)
}
data[name] = valuedata
}
return
} else {
return nil, fmt.Errorf("Encoder: EncoderToMap(invalid type %T)", v)
}
}
//redis 存储编码 针对 string 转换
func (this *Encoder) EncoderToSliceString(v interface{}) (data []string, err error) {
vof := reflect.ValueOf(v)
if !vof.IsValid() {
return nil, fmt.Errorf("Encoder: EncoderToSliceString(nil)")
}
if vof.Kind() != reflect.Ptr && vof.Kind() != reflect.Map && vof.Kind() != reflect.Slice {
return nil, fmt.Errorf("Encoder: EncoderToSliceString(non-pointer %T)", v)
}
// vof = vof.Elem()
if vof.Kind() == reflect.Slice {
data = make([]string, vof.Len())
for i := 0; i < vof.Len(); i++ {
value := vof.Index(i).Interface()
var valuedata string
if valuedata, err = this.EncoderString(value); err != nil {
return nil, fmt.Errorf("Encoder: EncoderToSliceString(invalid type %T) err:%v", value, err)
}
data[i] = valuedata
}
return
} else {
return nil, fmt.Errorf("Encoder: EncoderToSliceString(invalid type %T)", v)
}
}

View File

@ -5,7 +5,7 @@ import (
"reflect"
"unsafe"
"go_dreamfactory/lego/sys/codec/core"
"go_dreamfactory/lego/utils/codec/codecore"
"github.com/modern-go/reflect2"
)
@ -35,7 +35,7 @@ func (this sortableBindings) Swap(i, j int) {
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------------
func EncoderOfType(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
func EncoderOfType(ctx *codecore.Ctx, typ reflect2.Type) codecore.IEncoder {
encoder := ctx.Encoders[typ]
if encoder != nil {
return encoder
@ -47,8 +47,8 @@ func EncoderOfType(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
return encoder
}
func _createEncoderOfType(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
var encoder core.IEncoder
func _createEncoderOfType(ctx *codecore.Ctx, typ reflect2.Type) codecore.IEncoder {
var encoder codecore.IEncoder
encoder = createEncoderOfNative(ctx, typ)
if encoder != nil {
return encoder
@ -72,7 +72,7 @@ func _createEncoderOfType(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
}
}
func DecoderOfType(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
func DecoderOfType(ctx *codecore.Ctx, typ reflect2.Type) codecore.IDecoder {
decoder := ctx.Decoders[typ]
if decoder != nil {
return decoder
@ -84,8 +84,8 @@ func DecoderOfType(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
return decoder
}
func _createDecoderOfType(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
var decoder core.IDecoder
func _createDecoderOfType(ctx *codecore.Ctx, typ reflect2.Type) codecore.IDecoder {
var decoder codecore.IDecoder
decoder = createDecoderOfNative(ctx, typ)
if decoder != nil {
@ -129,25 +129,25 @@ func StringToBytes(s string) []byte {
//根节点 -------------------------------------------------------------------
type rootDecoder struct {
decoder core.IDecoder
decoder codecore.IDecoder
}
func (this *rootDecoder) GetType() reflect.Kind {
return reflect.Ptr
}
func (this *rootDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
this.decoder.Decode(ptr, extra)
func (this *rootDecoder) Decode(ptr unsafe.Pointer, r codecore.IReader) {
this.decoder.Decode(ptr, r)
}
type rootEncoder struct {
encoder core.IEncoder
encoder codecore.IEncoder
}
func (this *rootEncoder) GetType() reflect.Kind {
return reflect.Ptr
}
func (this *rootEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
this.encoder.Encode(ptr, stream)
func (this *rootEncoder) Encode(ptr unsafe.Pointer, w codecore.IWriter) {
this.encoder.Encode(ptr, w)
}
func (this *rootEncoder) IsEmpty(ptr unsafe.Pointer) bool {
@ -155,12 +155,12 @@ func (this *rootEncoder) IsEmpty(ptr unsafe.Pointer) bool {
}
//onePtrEncoder---------------------------------------------------------------
func NewonePtrEncoder(encoder core.IEncoder) core.IEncoder {
func NewonePtrEncoder(encoder codecore.IEncoder) codecore.IEncoder {
return &onePtrEncoder{encoder}
}
type onePtrEncoder struct {
encoder core.IEncoder
encoder codecore.IEncoder
}
func (this *onePtrEncoder) GetType() reflect.Kind {
@ -171,16 +171,16 @@ func (this *onePtrEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return this.encoder.IsEmpty(unsafe.Pointer(&ptr))
}
func (this *onePtrEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (this *onePtrEncoder) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
this.encoder.Encode(unsafe.Pointer(&ptr), stream)
}
func (this *onePtrEncoder) EncodeToMapJson(ptr unsafe.Pointer) (ret map[string]string, err error) {
if encoderMapJson, ok := this.encoder.(core.IEncoderMapJson); !ok {
func (this *onePtrEncoder) EncodeToMapJson(ptr unsafe.Pointer, w codecore.IWriter) (ret map[string]string, err error) {
if encoderMapJson, ok := this.encoder.(codecore.IEncoderMapJson); !ok {
err = fmt.Errorf("encoder %T not support EncodeToMapJson", this.encoder)
return
} else {
return encoderMapJson.EncodeToMapJson(unsafe.Pointer(&ptr))
return encoderMapJson.EncodeToMapJson(unsafe.Pointer(&ptr), w)
}
}
@ -192,7 +192,7 @@ type lazyErrorDecoder struct {
func (this *lazyErrorDecoder) GetType() reflect.Kind {
return reflect.Ptr
}
func (this *lazyErrorDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (this *lazyErrorDecoder) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
if extra.Error() == nil {
extra.SetErr(this.err)
}
@ -206,7 +206,7 @@ func (this *lazyErrorEncoder) GetType() reflect.Kind {
return reflect.Ptr
}
func (this *lazyErrorEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (this *lazyErrorEncoder) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
if ptr == nil {
stream.WriteNil()
} else if stream.Error() == nil {

View File

@ -7,37 +7,36 @@ import (
"reflect"
"unsafe"
"go_dreamfactory/lego/sys/codec/core"
"go_dreamfactory/lego/utils/codec/codecore"
"github.com/modern-go/reflect2"
)
func decoderOfArray(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
func decoderOfArray(ctx *codecore.Ctx, typ reflect2.Type) codecore.IDecoder {
arrayType := typ.(*reflect2.UnsafeArrayType)
decoder := DecoderOfType(ctx.Append("[arrayElem]"), arrayType.Elem())
return &arrayDecoder{ctx.ICodec, arrayType, decoder}
return &arrayDecoder{arrayType, decoder}
}
func encoderOfArray(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
func encoderOfArray(ctx *codecore.Ctx, typ reflect2.Type) codecore.IEncoder {
arrayType := typ.(*reflect2.UnsafeArrayType)
if arrayType.Len() == 0 {
return &emptyArrayEncoder{}
}
encoder := EncoderOfType(ctx.Append("[arrayElem]"), arrayType.Elem())
return &arrayEncoder{ctx.ICodec, arrayType, encoder}
return &arrayEncoder{arrayType, encoder}
}
//array-------------------------------------------------------------------------------------------------------------------------------
type arrayEncoder struct {
codec core.ICodec
arrayType *reflect2.UnsafeArrayType
elemEncoder core.IEncoder
elemEncoder codecore.IEncoder
}
func (codec *arrayEncoder) GetType() reflect.Kind {
return reflect.Array
}
func (this *arrayEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (this *arrayEncoder) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
stream.WriteArrayStart()
elemPtr := unsafe.Pointer(ptr)
this.elemEncoder.Encode(elemPtr, stream)
@ -57,32 +56,30 @@ func (this *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
}
//编码对象到json数组
func (this *arrayEncoder) EncodeToSliceJson(ptr unsafe.Pointer) (ret []string, err error) {
func (this *arrayEncoder) EncodeToSliceJson(ptr unsafe.Pointer, w codecore.IWriter) (ret []string, err error) {
ret = make([]string, this.arrayType.Len())
stream := this.codec.BorrowStream()
for i := 1; i < this.arrayType.Len(); i++ {
elemPtr := this.arrayType.UnsafeGetIndex(ptr, i)
this.elemEncoder.Encode(elemPtr, stream)
if stream.Error() != nil && stream.Error() != io.EOF {
err = stream.Error()
this.elemEncoder.Encode(elemPtr, w)
if w.Error() != nil && w.Error() != io.EOF {
err = w.Error()
return
}
ret[i] = BytesToString(stream.Buffer())
stream.Reset(512)
ret[i] = BytesToString(w.Buffer())
w.Reset()
}
return
}
type arrayDecoder struct {
codec core.ICodec
arrayType *reflect2.UnsafeArrayType
elemDecoder core.IDecoder
elemDecoder codecore.IDecoder
}
func (codec *arrayDecoder) GetType() reflect.Kind {
return reflect.Array
}
func (this *arrayDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (this *arrayDecoder) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
arrayType := this.arrayType
if extra.ReadNil() {
return
@ -110,20 +107,19 @@ func (this *arrayDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
}
}
func (this *arrayDecoder) DecodeForSliceJson(ptr unsafe.Pointer, data []string) (err error) {
func (this *arrayDecoder) DecodeForSliceJson(ptr unsafe.Pointer, r codecore.IReader, data []string) (err error) {
arrayType := this.arrayType
if data == nil {
err = errors.New("extra is nil")
return
}
extra := this.codec.BorrowExtractor([]byte{})
arrayType.UnsafeGetIndex(ptr, len(data))
for i, v := range data {
elemPtr := arrayType.UnsafeGetIndex(ptr, i)
extra.ResetBytes(StringToBytes(v))
this.elemDecoder.Decode(elemPtr, extra)
if extra.Error() != nil && extra.Error() != io.EOF {
err = extra.Error()
r.ResetBytes(StringToBytes(v))
this.elemDecoder.Decode(elemPtr, r)
if r.Error() != nil && r.Error() != io.EOF {
err = r.Error()
return
}
}
@ -136,7 +132,7 @@ func (this *emptyArrayEncoder) GetType() reflect.Kind {
return reflect.Array
}
func (this *emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (this *emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
stream.WriteEmptyArray()
}

View File

@ -5,7 +5,7 @@ import (
"reflect"
"unsafe"
"go_dreamfactory/lego/sys/codec/core"
"go_dreamfactory/lego/utils/codec/codecore"
"github.com/modern-go/reflect2"
)
@ -17,7 +17,7 @@ type dynamicEncoder struct {
func (codec *dynamicEncoder) GetType() reflect.Kind {
return reflect.Interface
}
func (encoder *dynamicEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (encoder *dynamicEncoder) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
obj := encoder.valType.UnsafeIndirect(ptr)
stream.WriteVal(obj)
}
@ -32,7 +32,7 @@ type efaceDecoder struct {
func (codec *efaceDecoder) GetType() reflect.Kind {
return reflect.Interface
}
func (decoder *efaceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (decoder *efaceDecoder) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
pObj := (*interface{})(ptr)
obj := *pObj
if obj == nil {
@ -46,7 +46,7 @@ func (decoder *efaceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
}
ptrType := typ.(*reflect2.UnsafePtrType)
ptrElemType := ptrType.Elem()
if extra.WhatIsNext() == core.NilValue {
if extra.WhatIsNext() == codecore.NilValue {
if ptrElemType.Kind() != reflect.Ptr {
extra.ReadNil()
*pObj = nil
@ -69,7 +69,7 @@ type ifaceDecoder struct {
func (codec *ifaceDecoder) GetType() reflect.Kind {
return reflect.Interface
}
func (decoder *ifaceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (decoder *ifaceDecoder) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
if extra.ReadNil() {
decoder.valType.UnsafeSet(ptr, decoder.valType.UnsafeNew())
return

View File

@ -4,19 +4,19 @@ import (
"fmt"
"io"
"reflect"
"sort"
"unsafe"
"go_dreamfactory/lego/sys/codec/core"
"go_dreamfactory/lego/utils/codec/codecore"
"github.com/modern-go/reflect2"
)
func decoderOfMap(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
func decoderOfMap(ctx *codecore.Ctx, typ reflect2.Type) codecore.IDecoder {
mapType := typ.(*reflect2.UnsafeMapType)
keyDecoder := decoderOfMapKey(ctx.Append("[mapKey]"), mapType.Key())
elemDecoder := DecoderOfType(ctx.Append("[mapElem]"), mapType.Elem())
return &mapDecoder{
codec: ctx.ICodec,
mapType: mapType,
keyType: mapType.Key(),
elemType: mapType.Elem(),
@ -25,17 +25,23 @@ func decoderOfMap(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
}
}
func encoderOfMap(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
func encoderOfMap(ctx *codecore.Ctx, typ reflect2.Type) codecore.IEncoder {
mapType := typ.(*reflect2.UnsafeMapType)
if ctx.Config.SortMapKeys {
return &sortKeysMapEncoder{
mapType: mapType,
keyEncoder: encoderOfMapKey(ctx.Append("[mapKey]"), mapType.Key()),
elemEncoder: EncoderOfType(ctx.Append("[mapElem]"), mapType.Elem()),
}
}
return &mapEncoder{
codec: ctx.ICodec,
mapType: mapType,
keyEncoder: encoderOfMapKey(ctx.Append("[mapKey]"), mapType.Key()),
elemEncoder: EncoderOfType(ctx.Append("[mapElem]"), mapType.Elem()),
}
}
func decoderOfMapKey(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
func decoderOfMapKey(ctx *codecore.Ctx, typ reflect2.Type) codecore.IDecoder {
switch typ.Kind() {
case reflect.String:
return DecoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
@ -54,7 +60,7 @@ func decoderOfMapKey(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
}
}
func encoderOfMapKey(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
func encoderOfMapKey(ctx *codecore.Ctx, typ reflect2.Type) codecore.IEncoder {
switch typ.Kind() {
case reflect.String:
return EncoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
@ -77,17 +83,72 @@ func encoderOfMapKey(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
}
//Map--------------------------------------------------------------------------------------------------------------------------------------
type mapEncoder struct {
codec core.ICodec
type sortKeysMapEncoder struct {
mapType *reflect2.UnsafeMapType
keyEncoder core.IEncoder
elemEncoder core.IEncoder
keyEncoder codecore.IEncoder
elemEncoder codecore.IEncoder
}
func (this *sortKeysMapEncoder) GetType() reflect.Kind {
return reflect.Map
}
func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, w codecore.IWriter) {
if *(*unsafe.Pointer)(ptr) == nil {
w.WriteNil()
return
}
w.WriteObjectStart()
mapIter := encoder.mapType.UnsafeIterate(ptr)
subStream := w.GetWriter()
subIter := w.GetReader(nil)
keyValues := encodedKeyValues{}
for mapIter.HasNext() {
key, elem := mapIter.UnsafeNext()
subStreamIndex := subStream.Buffered()
encoder.keyEncoder.Encode(key, subStream)
if subStream.Error() != nil && subStream.Error() != io.EOF && w.Error() == nil {
w.SetErr(subStream.Error())
}
encodedKey := subStream.Buffer()[subStreamIndex:]
subIter.ResetBytes(encodedKey)
decodedKey := subIter.ReadString()
subStream.WriteKVSplit()
encoder.elemEncoder.Encode(elem, subStream)
keyValues = append(keyValues, encodedKV{
key: decodedKey,
keyValue: subStream.Buffer()[subStreamIndex:],
})
}
sort.Sort(keyValues)
for i, keyValue := range keyValues {
if i != 0 {
w.WriteMemberSplit()
}
w.WriteBytes(keyValue.keyValue)
}
if subStream.Error() != nil && w.Error() == nil {
w.SetErr(subStream.Error())
}
w.WriteObjectEnd()
w.PutWriter(subStream)
w.PutReader(subIter)
}
func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
iter := encoder.mapType.UnsafeIterate(ptr)
return !iter.HasNext()
}
type mapEncoder struct {
mapType *reflect2.UnsafeMapType
keyEncoder codecore.IEncoder
elemEncoder codecore.IEncoder
}
func (this *mapEncoder) GetType() reflect.Kind {
return reflect.Map
}
func (this *mapEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (this *mapEncoder) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
if *(*unsafe.Pointer)(ptr) == nil {
stream.WriteNil()
return
@ -106,14 +167,17 @@ func (this *mapEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
stream.WriteObjectEnd()
}
func (this *mapEncoder) EncodeToMapJson(ptr unsafe.Pointer) (ret map[string]string, err error) {
func (this *mapEncoder) EncodeToMapJson(ptr unsafe.Pointer, w codecore.IWriter) (ret map[string]string, err error) {
ret = make(map[string]string)
var (
k, v string
)
keystream := this.codec.BorrowStream()
elemstream := this.codec.BorrowStream()
keystream := w.GetWriter()
elemstream := w.GetWriter()
defer func() {
w.PutWriter(keystream)
w.PutWriter(elemstream)
}()
iter := this.mapType.UnsafeIterate(ptr)
for i := 0; iter.HasNext(); i++ {
key, elem := iter.UnsafeNext()
@ -138,8 +202,8 @@ func (this *mapEncoder) EncodeToMapJson(ptr unsafe.Pointer) (ret map[string]stri
v = *((*string)(elem))
}
ret[k] = v
keystream.Reset(512)
elemstream.Reset(512)
keystream.Reset()
elemstream.Reset()
}
return
}
@ -150,18 +214,17 @@ func (this *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
}
type mapDecoder struct {
codec core.ICodec
mapType *reflect2.UnsafeMapType
keyType reflect2.Type
elemType reflect2.Type
keyDecoder core.IDecoder
elemDecoder core.IDecoder
keyDecoder codecore.IDecoder
elemDecoder codecore.IDecoder
}
func (codec *mapDecoder) GetType() reflect.Kind {
return reflect.Map
}
func (this *mapDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (this *mapDecoder) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
mapType := this.mapType
if extra.ReadNil() {
*(*unsafe.Pointer)(ptr) = nil
@ -200,9 +263,13 @@ func (this *mapDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
}
//解码对象从MapJson 中
func (this *mapDecoder) DecodeForMapJson(ptr unsafe.Pointer, extra map[string]string) (err error) {
keyext := this.codec.BorrowExtractor([]byte{})
elemext := this.codec.BorrowExtractor([]byte{})
func (this *mapDecoder) DecodeForMapJson(ptr unsafe.Pointer, r codecore.IReader, extra map[string]string) (err error) {
keyext := r.GetReader([]byte{})
elemext := r.GetReader([]byte{})
defer func() {
r.PutReader(keyext)
r.PutReader(keyext)
}()
for k, v := range extra {
key := this.keyType.UnsafeNew()
if this.keyDecoder.GetType() != reflect.String {
@ -233,13 +300,13 @@ func (this *mapDecoder) DecodeForMapJson(ptr unsafe.Pointer, extra map[string]st
//NumericMap-------------------------------------------------------------------------------------------------------------------------------
type numericMapKeyDecoder struct {
decoder core.IDecoder
decoder codecore.IDecoder
}
func (this *numericMapKeyDecoder) GetType() reflect.Kind {
return this.decoder.GetType()
}
func (this *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (this *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
if !extra.ReadKeyStart() {
return
}
@ -250,13 +317,13 @@ func (this *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, extra core.IExtract
}
type numericMapKeyEncoder struct {
encoder core.IEncoder
encoder codecore.IEncoder
}
func (this *numericMapKeyEncoder) GetType() reflect.Kind {
return this.encoder.GetType()
}
func (this *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (this *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
stream.WriteKeyStart()
this.encoder.Encode(ptr, stream)
stream.WriteKeyEnd()
@ -268,7 +335,7 @@ func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
//------------------------------------------------------------------------------------------------------------------
type dynamicMapKeyEncoder struct {
ctx *core.Ctx
ctx *codecore.Ctx
valType reflect2.Type
}
@ -276,7 +343,7 @@ func (this *dynamicMapKeyEncoder) GetType() reflect.Kind {
return reflect.Interface
}
func (this *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (this *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
obj := this.valType.UnsafeIndirect(ptr)
encoderOfMapKey(this.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream)
}
@ -285,3 +352,14 @@ func (this *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
obj := this.valType.UnsafeIndirect(ptr)
return encoderOfMapKey(this.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj))
}
type encodedKeyValues []encodedKV
type encodedKV struct {
key string
keyValue []byte
}
func (sv encodedKeyValues) Len() int { return len(sv) }
func (sv encodedKeyValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key }

View File

@ -5,14 +5,14 @@ import (
"strconv"
"unsafe"
"go_dreamfactory/lego/sys/codec/core"
"go_dreamfactory/lego/utils/codec/codecore"
"github.com/modern-go/reflect2"
)
const ptrSize = 32 << uintptr(^uintptr(0)>>63) //计算int的大小 是32 还是64
func createDecoderOfNative(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
func createDecoderOfNative(ctx *codecore.Ctx, typ reflect2.Type) codecore.IDecoder {
typeName := typ.String()
switch typ.Kind() {
case reflect.String:
@ -103,7 +103,7 @@ func createDecoderOfNative(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
return nil
}
func createEncoderOfNative(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
func createEncoderOfNative(ctx *codecore.Ctx, typ reflect2.Type) codecore.IEncoder {
typeName := typ.String()
kind := typ.Kind()
switch kind {
@ -201,11 +201,11 @@ type stringCodec struct {
func (codec *stringCodec) GetType() reflect.Kind {
return reflect.String
}
func (codec *stringCodec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (codec *stringCodec) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
*((*string)(ptr)) = extra.ReadString()
}
func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
str := *((*string)(ptr))
stream.WriteString(str)
}
@ -221,13 +221,13 @@ func (codec *int8Codec) GetType() reflect.Kind {
return reflect.Int8
}
func (codec *int8Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (codec *int8Codec) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
if !extra.ReadNil() {
*((*int8)(ptr)) = extra.ReadInt8()
}
}
func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
stream.WriteInt8(*((*int8)(ptr)))
}
@ -241,13 +241,13 @@ type int16Codec struct {
func (codec *int16Codec) GetType() reflect.Kind {
return reflect.Int16
}
func (codec *int16Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (codec *int16Codec) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
if !extra.ReadNil() {
*((*int16)(ptr)) = extra.ReadInt16()
}
}
func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
stream.WriteInt16(*((*int16)(ptr)))
}
@ -261,13 +261,13 @@ type int32Codec struct {
func (codec *int32Codec) GetType() reflect.Kind {
return reflect.Int32
}
func (codec *int32Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (codec *int32Codec) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
if !extra.ReadNil() {
*((*int32)(ptr)) = extra.ReadInt32()
}
}
func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
stream.WriteInt32(*((*int32)(ptr)))
}
func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool {
@ -280,13 +280,13 @@ type int64Codec struct {
func (codec *int64Codec) GetType() reflect.Kind {
return reflect.Int64
}
func (codec *int64Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (codec *int64Codec) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
if !extra.ReadNil() {
*((*int64)(ptr)) = extra.ReadInt64()
}
}
func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
stream.WriteInt64(*((*int64)(ptr)))
}
@ -300,13 +300,13 @@ type uint8Codec struct {
func (codec *uint8Codec) GetType() reflect.Kind {
return reflect.Uint8
}
func (codec *uint8Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (codec *uint8Codec) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
if !extra.ReadNil() {
*((*uint8)(ptr)) = extra.ReadUint8()
}
}
func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
stream.WriteUint8(*((*uint8)(ptr)))
}
@ -320,13 +320,13 @@ type uint16Codec struct {
func (codec *uint16Codec) GetType() reflect.Kind {
return reflect.Uint16
}
func (codec *uint16Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (codec *uint16Codec) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
if !extra.ReadNil() {
*((*uint16)(ptr)) = extra.ReadUint16()
}
}
func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
stream.WriteUint16(*((*uint16)(ptr)))
}
@ -340,13 +340,13 @@ type uint32Codec struct {
func (codec *uint32Codec) GetType() reflect.Kind {
return reflect.Uint32
}
func (codec *uint32Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (codec *uint32Codec) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
if !extra.ReadNil() {
*((*uint32)(ptr)) = extra.ReadUint32()
}
}
func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
stream.WriteUint32(*((*uint32)(ptr)))
}
func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool {
@ -359,13 +359,13 @@ type uint64Codec struct {
func (codec *uint64Codec) GetType() reflect.Kind {
return reflect.Uint64
}
func (codec *uint64Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (codec *uint64Codec) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
if !extra.ReadNil() {
*((*uint64)(ptr)) = extra.ReadUint64()
}
}
func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
stream.WriteUint64(*((*uint64)(ptr)))
}
@ -379,13 +379,13 @@ type float32Codec struct {
func (codec *float32Codec) GetType() reflect.Kind {
return reflect.Float32
}
func (codec *float32Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (codec *float32Codec) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
if !extra.ReadNil() {
*((*float32)(ptr)) = extra.ReadFloat32()
}
}
func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
stream.WriteFloat32(*((*float32)(ptr)))
}
@ -399,13 +399,13 @@ type float64Codec struct {
func (codec *float64Codec) GetType() reflect.Kind {
return reflect.Float64
}
func (codec *float64Codec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (codec *float64Codec) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
if !extra.ReadNil() {
*((*float64)(ptr)) = extra.ReadFloat64()
}
}
func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
stream.WriteFloat64(*((*float64)(ptr)))
}
@ -419,13 +419,13 @@ type boolCodec struct {
func (codec *boolCodec) GetType() reflect.Kind {
return reflect.Bool
}
func (codec *boolCodec) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (codec *boolCodec) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
if !extra.ReadNil() {
*((*bool)(ptr)) = extra.ReadBool()
}
}
func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
stream.WriteBool(*((*bool)(ptr)))
}

View File

@ -5,19 +5,19 @@ import (
"reflect"
"unsafe"
"go_dreamfactory/lego/sys/codec/core"
"go_dreamfactory/lego/utils/codec/codecore"
"github.com/modern-go/reflect2"
)
func decoderOfOptional(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
func decoderOfOptional(ctx *codecore.Ctx, typ reflect2.Type) codecore.IDecoder {
ptrType := typ.(*reflect2.UnsafePtrType)
elemType := ptrType.Elem()
decoder := DecoderOfType(ctx, elemType)
return &OptionalDecoder{elemType, decoder}
}
func encoderOfOptional(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
func encoderOfOptional(ctx *codecore.Ctx, typ reflect2.Type) codecore.IEncoder {
ptrType := typ.(*reflect2.UnsafePtrType)
elemType := ptrType.Elem()
elemEncoder := EncoderOfType(ctx, elemType)
@ -28,13 +28,13 @@ func encoderOfOptional(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
//Optional--------------------------------------------------------------------------------------------------------------------
type OptionalDecoder struct {
ValueType reflect2.Type
ValueDecoder core.IDecoder
ValueDecoder codecore.IDecoder
}
func (this *OptionalDecoder) GetType() reflect.Kind {
return this.ValueDecoder.GetType()
}
func (this *OptionalDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (this *OptionalDecoder) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
if extra.ReadNil() {
*((*unsafe.Pointer)(ptr)) = nil
} else {
@ -48,23 +48,23 @@ func (this *OptionalDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
}
}
func (this *OptionalDecoder) DecodeForMapJson(ptr unsafe.Pointer, extra map[string]string) (err error) {
if decoderMapJson, ok := this.ValueDecoder.(core.IDecoderMapJson); !ok {
func (this *OptionalDecoder) DecodeForMapJson(ptr unsafe.Pointer, r codecore.IReader, extra map[string]string) (err error) {
if decoderMapJson, ok := this.ValueDecoder.(codecore.IDecoderMapJson); !ok {
err = fmt.Errorf("encoder %T not support EncodeToMapJson", this.ValueDecoder)
return
} else {
return decoderMapJson.DecodeForMapJson(ptr, extra)
return decoderMapJson.DecodeForMapJson(ptr, r, extra)
}
}
type OptionalEncoder struct {
ValueEncoder core.IEncoder
ValueEncoder codecore.IEncoder
}
func (this *OptionalEncoder) GetType() reflect.Kind {
return this.ValueEncoder.GetType()
}
func (this *OptionalEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (this *OptionalEncoder) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
if *((*unsafe.Pointer)(ptr)) == nil {
stream.WriteNil()
} else {
@ -76,8 +76,8 @@ func (this *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return *((*unsafe.Pointer)(ptr)) == nil
}
func (this *OptionalEncoder) EncodeToMapJson(ptr unsafe.Pointer) (ret map[string]string, err error) {
if encoderMapJson, ok := this.ValueEncoder.(core.IEncoderMapJson); !ok {
func (this *OptionalEncoder) EncodeToMapJson(ptr unsafe.Pointer, w codecore.IWriter) (ret map[string]string, err error) {
if encoderMapJson, ok := this.ValueEncoder.(codecore.IEncoderMapJson); !ok {
err = fmt.Errorf("encoder %T not support EncodeToMapJson", this.ValueEncoder)
return
} else {
@ -85,17 +85,17 @@ func (this *OptionalEncoder) EncodeToMapJson(ptr unsafe.Pointer) (ret map[string
err = fmt.Errorf("encoder ptr is nil")
return
} else {
return encoderMapJson.EncodeToMapJson(*((*unsafe.Pointer)(ptr)))
return encoderMapJson.EncodeToMapJson(*((*unsafe.Pointer)(ptr)), w)
}
}
}
//reference--------------------------------------------------------------------------------------------------------------------
type referenceEncoder struct {
encoder core.IEncoder
encoder codecore.IEncoder
}
func (this *referenceEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (this *referenceEncoder) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
this.encoder.Encode(unsafe.Pointer(&ptr), stream)
}
@ -104,23 +104,23 @@ func (this *referenceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
}
type referenceDecoder struct {
decoder core.IDecoder
decoder codecore.IDecoder
}
func (this *referenceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (this *referenceDecoder) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
this.decoder.Decode(unsafe.Pointer(&ptr), extra)
}
//dereference--------------------------------------------------------------------------------------------------------------------
type dereferenceDecoder struct {
valueType reflect2.Type
valueDecoder core.IDecoder
valueDecoder codecore.IDecoder
}
func (this *dereferenceDecoder) GetType() reflect.Kind {
return this.valueDecoder.GetType()
}
func (this *dereferenceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (this *dereferenceDecoder) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
if *((*unsafe.Pointer)(ptr)) == nil {
newPtr := this.valueType.UnsafeNew()
this.valueDecoder.Decode(newPtr, extra)
@ -131,13 +131,13 @@ func (this *dereferenceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor
}
type dereferenceEncoder struct {
ValueEncoder core.IEncoder
ValueEncoder codecore.IEncoder
}
func (this *dereferenceEncoder) GetType() reflect.Kind {
return this.ValueEncoder.GetType()
}
func (this *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (this *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
if *((*unsafe.Pointer)(ptr)) == nil {
stream.WriteNil()
} else {
@ -158,7 +158,7 @@ func (this *dereferenceEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool {
if deReferenced == nil {
return true
}
isEmbeddedPtrNil, converted := this.ValueEncoder.(core.IsEmbeddedPtrNil)
isEmbeddedPtrNil, converted := this.ValueEncoder.(codecore.IsEmbeddedPtrNil)
if !converted {
return false
}

View File

@ -7,32 +7,31 @@ import (
"reflect"
"unsafe"
"go_dreamfactory/lego/sys/codec/core"
"go_dreamfactory/lego/utils/codec/codecore"
"github.com/modern-go/reflect2"
)
func decoderOfSlice(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
func decoderOfSlice(ctx *codecore.Ctx, typ reflect2.Type) codecore.IDecoder {
sliceType := typ.(*reflect2.UnsafeSliceType)
decoder := DecoderOfType(ctx.Append("[sliceElem]"), sliceType.Elem())
return &sliceDecoder{ctx.ICodec, sliceType, decoder}
return &sliceDecoder{sliceType, decoder}
}
func encoderOfSlice(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
func encoderOfSlice(ctx *codecore.Ctx, typ reflect2.Type) codecore.IEncoder {
sliceType := typ.(*reflect2.UnsafeSliceType)
encoder := EncoderOfType(ctx.Append("[sliceElem]"), sliceType.Elem())
return &sliceEncoder{ctx.ICodec, sliceType, encoder}
return &sliceEncoder{sliceType, encoder}
}
type sliceEncoder struct {
codec core.ICodec
sliceType *reflect2.UnsafeSliceType
elemEncoder core.IEncoder
elemEncoder codecore.IEncoder
}
func (codec *sliceEncoder) GetType() reflect.Kind {
return reflect.Slice
}
func (this *sliceEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (this *sliceEncoder) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
if this.sliceType.UnsafeIsNil(ptr) {
stream.WriteNil()
return
@ -60,7 +59,7 @@ func (this *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
}
//编码对象到json数组
func (this *sliceEncoder) EncodeToSliceJson(ptr unsafe.Pointer) (ret []string, err error) {
func (this *sliceEncoder) EncodeToSliceJson(ptr unsafe.Pointer, w codecore.IWriter) (ret []string, err error) {
if this.sliceType.UnsafeIsNil(ptr) {
err = errors.New("val is nil")
return
@ -70,30 +69,28 @@ func (this *sliceEncoder) EncodeToSliceJson(ptr unsafe.Pointer) (ret []string, e
if length == 0 {
return
}
stream := this.codec.BorrowStream()
for i := 1; i < length; i++ {
elemPtr := this.sliceType.UnsafeGetIndex(ptr, i)
this.elemEncoder.Encode(elemPtr, stream)
if stream.Error() != nil && stream.Error() != io.EOF {
err = stream.Error()
this.elemEncoder.Encode(elemPtr, w)
if w.Error() != nil && w.Error() != io.EOF {
err = w.Error()
return
}
ret[i] = BytesToString(stream.Buffer())
stream.Reset(512)
ret[i] = BytesToString(w.Buffer())
w.Reset()
}
return
}
type sliceDecoder struct {
codec core.ICodec
sliceType *reflect2.UnsafeSliceType
elemDecoder core.IDecoder
elemDecoder codecore.IDecoder
}
func (codec *sliceDecoder) GetType() reflect.Kind {
return reflect.Slice
}
func (this *sliceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (this *sliceDecoder) Decode(ptr unsafe.Pointer, extra codecore.IReader) {
sliceType := this.sliceType
if extra.ReadNil() {
sliceType.UnsafeSetNil(ptr)
@ -125,20 +122,19 @@ func (this *sliceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
}
}
func (this *sliceDecoder) DecodeForSliceJson(ptr unsafe.Pointer, data []string) (err error) {
func (this *sliceDecoder) DecodeForSliceJson(ptr unsafe.Pointer, r codecore.IReader, data []string) (err error) {
sliceType := this.sliceType
if data == nil {
err = errors.New("extra is nil")
return
}
extra := this.codec.BorrowExtractor([]byte{})
sliceType.UnsafeGrow(ptr, len(data))
for i, v := range data {
elemPtr := sliceType.UnsafeGetIndex(ptr, i)
extra.ResetBytes(StringToBytes(v))
this.elemDecoder.Decode(elemPtr, extra)
if extra.Error() != nil && extra.Error() != io.EOF {
err = extra.Error()
r.ResetBytes(StringToBytes(v))
this.elemDecoder.Decode(elemPtr, r)
if r.Error() != nil && r.Error() != io.EOF {
err = r.Error()
return
}
}

View File

@ -10,7 +10,7 @@ import (
"unicode"
"unsafe"
"go_dreamfactory/lego/sys/codec/core"
"go_dreamfactory/lego/utils/codec/codecore"
"github.com/modern-go/reflect2"
)
@ -25,11 +25,11 @@ type Binding struct {
Field reflect2.StructField
FromNames []string
ToNames []string
Encoder core.IEncoder
Decoder core.IDecoder
Encoder codecore.IEncoder
Decoder codecore.IDecoder
}
func encoderOfStruct(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
func encoderOfStruct(ctx *codecore.Ctx, typ reflect2.Type) codecore.IEncoder {
type bindingTo struct {
binding *Binding
toName string
@ -47,7 +47,7 @@ func encoderOfStruct(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
if old.toName != toName {
continue
}
old.ignored, new.ignored = resolveConflictBinding(ctx.Options(), old.binding, new.binding)
old.ignored, new.ignored = resolveConflictBinding(ctx.Config, old.binding, new.binding)
}
orderedBindings = append(orderedBindings, new)
}
@ -64,10 +64,10 @@ func encoderOfStruct(ctx *core.Ctx, typ reflect2.Type) core.IEncoder {
})
}
}
return &structEncoder{ctx.ICodec, typ, finalOrderedFields}
return &structEncoder{typ, finalOrderedFields}
}
func decoderOfStruct(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
func decoderOfStruct(ctx *codecore.Ctx, typ reflect2.Type) codecore.IDecoder {
bindings := map[string]*Binding{}
structDescriptor := describeStruct(ctx, typ)
for _, binding := range structDescriptor.Fields {
@ -77,7 +77,7 @@ func decoderOfStruct(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
bindings[fromName] = binding
continue
}
ignoreOld, ignoreNew := resolveConflictBinding(ctx.Options(), old, binding)
ignoreOld, ignoreNew := resolveConflictBinding(ctx.Config, old, binding)
if ignoreOld {
delete(bindings, fromName)
}
@ -91,25 +91,25 @@ func decoderOfStruct(ctx *core.Ctx, typ reflect2.Type) core.IDecoder {
fields[k] = binding.Decoder.(*structFieldDecoder)
}
if !ctx.Options().CaseSensitive {
if !ctx.Config.CaseSensitive {
for k, binding := range bindings {
if _, found := fields[strings.ToLower(k)]; !found {
fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder)
}
}
}
return createStructDecoder(ctx.ICodec, typ, fields)
return &structDecoder{ctx.Config, typ, fields}
}
//结构第编辑码构建
func describeStruct(ctx *core.Ctx, typ reflect2.Type) *StructDescriptor {
func describeStruct(ctx *codecore.Ctx, typ reflect2.Type) *StructDescriptor {
structType := typ.(*reflect2.UnsafeStructType)
embeddedBindings := []*Binding{}
bindings := []*Binding{}
for i := 0; i < structType.NumField(); i++ {
field := structType.Field(i)
tag, hastag := field.Tag().Lookup(ctx.Options().TagKey)
if ctx.Options().OnlyTaggedField && !hastag && !field.Anonymous() {
tag, hastag := field.Tag().Lookup(ctx.Config.TagKey)
if ctx.Config.OnlyTaggedField && !hastag && !field.Anonymous() {
continue
}
if tag == "-" || field.Name() == "_" {
@ -160,22 +160,22 @@ func describeStruct(ctx *core.Ctx, typ reflect2.Type) *StructDescriptor {
return createStructDescriptor(ctx, typ, bindings, embeddedBindings)
}
func createStructDescriptor(ctx *core.Ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor {
func createStructDescriptor(ctx *codecore.Ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor {
structDescriptor := &StructDescriptor{
Type: typ,
Fields: bindings,
}
processTags(structDescriptor, ctx.ICodec)
processTags(structDescriptor, ctx.Config)
allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...))
sort.Sort(allBindings)
structDescriptor.Fields = allBindings
return structDescriptor
}
func processTags(structDescriptor *StructDescriptor, codec core.ICodec) {
func processTags(structDescriptor *StructDescriptor, config *codecore.Config) {
for _, binding := range structDescriptor.Fields {
shouldOmitEmpty := false
tagParts := strings.Split(binding.Field.Tag().Get(codec.Options().TagKey), ",")
tagParts := strings.Split(binding.Field.Tag().Get(config.TagKey), ",")
for _, tagPart := range tagParts[1:] {
if tagPart == "omitempty" {
shouldOmitEmpty = true
@ -206,17 +206,9 @@ func calcFieldNames(originalFieldName string, tagProvidedFieldName string, whole
return fieldNames
}
func createStructDecoder(codec core.ICodec, typ reflect2.Type, fields map[string]*structFieldDecoder) core.IDecoder {
if codec.Options().DisallowUnknownFields {
return &structDecoder{typ: typ, fields: fields, disallowUnknownFields: true}
} else {
return &structDecoder{codec, typ, fields, false}
}
}
func resolveConflictBinding(opt *core.Options, old, new *Binding) (ignoreOld, ignoreNew bool) {
newTagged := new.Field.Tag().Get(opt.TagKey) != ""
oldTagged := old.Field.Tag().Get(opt.TagKey) != ""
func resolveConflictBinding(config *codecore.Config, old, new *Binding) (ignoreOld, ignoreNew bool) {
newTagged := new.Field.Tag().Get(config.TagKey) != ""
oldTagged := old.Field.Tag().Get(config.TagKey) != ""
if newTagged {
if oldTagged {
if len(old.levels) > len(new.levels) {
@ -245,7 +237,6 @@ func resolveConflictBinding(opt *core.Options, old, new *Binding) (ignoreOld, ig
//结构对象 编解码-----------------------------------------------------------------------------------------------------------------------
type structEncoder struct {
codec core.ICodec
typ reflect2.Type
fields []structFieldTo
}
@ -253,7 +244,7 @@ type structEncoder struct {
func (codec *structEncoder) GetType() reflect.Kind {
return reflect.Struct
}
func (this *structEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (this *structEncoder) Encode(ptr unsafe.Pointer, stream codecore.IWriter) {
stream.WriteObjectStart()
isNotFirst := false
for _, field := range this.fields {
@ -276,9 +267,8 @@ func (this *structEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
}
}
func (this *structEncoder) EncodeToMapJson(ptr unsafe.Pointer) (ret map[string]string, err error) {
func (this *structEncoder) EncodeToMapJson(ptr unsafe.Pointer, w codecore.IWriter) (ret map[string]string, err error) {
ret = make(map[string]string)
stream := this.codec.BorrowStream()
for _, field := range this.fields {
if field.encoder.omitempty && field.encoder.IsEmpty(ptr) {
continue
@ -286,13 +276,13 @@ func (this *structEncoder) EncodeToMapJson(ptr unsafe.Pointer) (ret map[string]s
if field.encoder.IsEmbeddedPtrNil(ptr) {
continue
}
stream.Reset(512)
field.encoder.Encode(ptr, stream)
if stream.Error() != nil && stream.Error() != io.EOF {
err = stream.Error()
w.Reset()
field.encoder.Encode(ptr, w)
if w.Error() != nil && w.Error() != io.EOF {
err = w.Error()
return
}
ret[field.toName] = BytesToString(stream.Buffer())
ret[field.toName] = BytesToString(w.Buffer())
}
return
}
@ -302,68 +292,67 @@ func (this *structEncoder) IsEmpty(ptr unsafe.Pointer) bool {
}
type structDecoder struct {
codec core.ICodec
config *codecore.Config
typ reflect2.Type
fields map[string]*structFieldDecoder
disallowUnknownFields bool
}
func (codec *structDecoder) GetType() reflect.Kind {
return reflect.Struct
}
func (this *structDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
if !extra.ReadObjectStart() {
func (this *structDecoder) Decode(ptr unsafe.Pointer, r codecore.IReader) {
if !r.ReadObjectStart() {
return
}
this.decodeField(ptr, extra)
for extra.ReadMemberSplit() {
this.decodeField(ptr, extra)
this.decodeField(ptr, r)
for r.ReadMemberSplit() {
this.decodeField(ptr, r)
}
if extra.Error() != nil && extra.Error() != io.EOF && len(this.typ.Type1().Name()) != 0 {
extra.SetErr(fmt.Errorf("%v.%s", this.typ, extra.Error().Error()))
if r.Error() != nil && r.Error() != io.EOF && len(this.typ.Type1().Name()) != 0 {
r.SetErr(fmt.Errorf("%v.%s", this.typ, r.Error().Error()))
}
extra.ReadObjectEnd()
r.ReadObjectEnd()
}
func (this *structDecoder) decodeField(ptr unsafe.Pointer, extra core.IExtractor) {
func (this *structDecoder) decodeField(ptr unsafe.Pointer, r codecore.IReader) {
var field string
var fieldDecoder *structFieldDecoder
field = extra.ReadString()
field = r.ReadString()
fieldDecoder = this.fields[field]
if fieldDecoder == nil && !this.codec.Options().CaseSensitive {
if fieldDecoder == nil && !this.config.CaseSensitive {
fieldDecoder = this.fields[strings.ToLower(field)]
}
if fieldDecoder == nil {
if this.disallowUnknownFields {
if this.config.DisallowUnknownFields {
msg := "found unknown field: " + field
extra.SetErr(fmt.Errorf("decodeField %s", msg))
r.SetErr(fmt.Errorf("decodeField %s", msg))
return
}
if !extra.ReadKVSplit() {
if !r.ReadKVSplit() {
return
}
extra.Skip() //跳过一个数据单元
r.Skip() //跳过一个数据单元
return
}
if !extra.ReadKVSplit() {
if !r.ReadKVSplit() {
return
}
fieldDecoder.Decode(ptr, extra)
fieldDecoder.Decode(ptr, r)
}
//解码对象从MapJson 中
func (this *structDecoder) DecodeForMapJson(ptr unsafe.Pointer, extra map[string]string) (err error) {
func (this *structDecoder) DecodeForMapJson(ptr unsafe.Pointer, r codecore.IReader, extra map[string]string) (err error) {
var fieldDecoder *structFieldDecoder
ext := this.codec.BorrowExtractor([]byte{})
ext := r.GetReader([]byte{})
for k, v := range extra {
fieldDecoder = this.fields[k]
if fieldDecoder == nil && !this.codec.Options().CaseSensitive {
if fieldDecoder == nil && !this.config.CaseSensitive {
fieldDecoder = this.fields[strings.ToLower(k)]
}
if fieldDecoder == nil {
if this.disallowUnknownFields {
if this.config.DisallowUnknownFields {
err = errors.New("found unknown field: " + k)
return
}
@ -386,18 +375,18 @@ type structFieldTo struct {
}
type structFieldEncoder struct {
field reflect2.StructField
fieldEncoder core.IEncoder
fieldEncoder codecore.IEncoder
omitempty bool
}
func (this *structFieldEncoder) GetType() reflect.Kind {
return this.fieldEncoder.GetType()
}
func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, w codecore.IWriter) {
fieldPtr := encoder.field.UnsafeGet(ptr)
encoder.fieldEncoder.Encode(fieldPtr, stream)
if stream.Error() != nil && stream.Error() != io.EOF {
stream.SetErr(fmt.Errorf("%s: %s", encoder.field.Name(), stream.Error().Error()))
encoder.fieldEncoder.Encode(fieldPtr, w)
if w.Error() != nil && w.Error() != io.EOF {
w.SetErr(fmt.Errorf("%s: %s", encoder.field.Name(), w.Error().Error()))
}
}
@ -407,7 +396,7 @@ func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool {
}
func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool {
isEmbeddedPtrNil, converted := encoder.fieldEncoder.(core.IsEmbeddedPtrNil)
isEmbeddedPtrNil, converted := encoder.fieldEncoder.(codecore.IsEmbeddedPtrNil)
if !converted {
return false
}
@ -417,17 +406,17 @@ func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool {
type structFieldDecoder struct {
field reflect2.StructField
fieldDecoder core.IDecoder
fieldDecoder codecore.IDecoder
}
func (this *structFieldDecoder) GetType() reflect.Kind {
return this.fieldDecoder.GetType()
}
func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) {
func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, r codecore.IReader) {
fieldPtr := decoder.field.UnsafeGet(ptr)
decoder.fieldDecoder.Decode(fieldPtr, extra)
if extra.Error() != nil && extra.Error() != io.EOF {
extra.SetErr(fmt.Errorf("%s: %s", decoder.field.Name(), extra.Error().Error()))
decoder.fieldDecoder.Decode(fieldPtr, r)
if r.Error() != nil && r.Error() != io.EOF {
r.SetErr(fmt.Errorf("%s: %s", decoder.field.Name(), r.Error().Error()))
}
}
@ -438,8 +427,8 @@ type emptyStructEncoder struct {
func (codec *emptyStructEncoder) GetType() reflect.Kind {
return reflect.Struct
}
func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) {
stream.WriteEmptyObject()
func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, w codecore.IWriter) {
w.WriteEmptyObject()
}
func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool {

View File

@ -0,0 +1,221 @@
package json
import (
"errors"
"fmt"
"reflect"
"sync"
"go_dreamfactory/lego/utils/codec"
"go_dreamfactory/lego/utils/codec/codecore"
"github.com/modern-go/reflect2"
)
const defsize = 512
var writerPool = &sync.Pool{
New: func() interface{} {
return &JsonWriter{
buf: make([]byte, 0, defsize),
err: nil,
indention: 0,
}
},
}
func GetReader(buf []byte) codecore.IReader {
reader := readerPool.Get().(codecore.IReader)
reader.ResetBytes(buf)
return reader
}
func PutReader(r codecore.IReader) {
readerPool.Put(r)
}
var readerPool = &sync.Pool{
New: func() interface{} {
return &JsonReader{
buf: nil,
head: 0,
tail: 0,
depth: 0,
err: nil,
}
},
}
func GetWriter() codecore.IWriter {
writer := writerPool.Get().(codecore.IWriter)
return writer
}
func PutWriter(w codecore.IWriter) {
writerPool.Put(w)
}
const maxDepth = 10000
var hexDigits []byte
var valueTypes []codecore.ValueType
func init() {
hexDigits = make([]byte, 256)
for i := 0; i < len(hexDigits); i++ {
hexDigits[i] = 255
}
for i := '0'; i <= '9'; i++ {
hexDigits[i] = byte(i - '0')
}
for i := 'a'; i <= 'f'; i++ {
hexDigits[i] = byte((i - 'a') + 10)
}
for i := 'A'; i <= 'F'; i++ {
hexDigits[i] = byte((i - 'A') + 10)
}
valueTypes = make([]codecore.ValueType, 256)
for i := 0; i < len(valueTypes); i++ {
valueTypes[i] = codecore.InvalidValue
}
valueTypes['"'] = codecore.StringValue
valueTypes['-'] = codecore.NumberValue
valueTypes['0'] = codecore.NumberValue
valueTypes['1'] = codecore.NumberValue
valueTypes['2'] = codecore.NumberValue
valueTypes['3'] = codecore.NumberValue
valueTypes['4'] = codecore.NumberValue
valueTypes['5'] = codecore.NumberValue
valueTypes['6'] = codecore.NumberValue
valueTypes['7'] = codecore.NumberValue
valueTypes['8'] = codecore.NumberValue
valueTypes['9'] = codecore.NumberValue
valueTypes['t'] = codecore.BoolValue
valueTypes['f'] = codecore.BoolValue
valueTypes['n'] = codecore.NilValue
valueTypes['['] = codecore.ArrayValue
valueTypes['{'] = codecore.ObjectValue
}
var defconf = &codecore.Config{
SortMapKeys: true,
IndentionStep: 1,
OnlyTaggedField: false,
DisallowUnknownFields: false,
CaseSensitive: false,
TagKey: "json",
}
func Marshal(val interface{}) (buf []byte, err error) {
writer := GetWriter()
defer PutWriter(writer)
writer.WriteVal(val)
if writer.Error() != nil {
return nil, writer.Error()
}
result := writer.Buffer()
copied := make([]byte, len(result))
copy(copied, result)
return copied, nil
}
func Unmarshal(data []byte, v interface{}) error {
extra := GetReader(data)
defer PutReader(extra)
extra.ReadVal(v)
return extra.Error()
}
func MarshalMap(val interface{}) (ret map[string]string, err error) {
if nil == val {
err = errors.New("val is null")
return
}
cacheKey := reflect2.RTypeOf(val)
encoder := codec.GetEncoder(cacheKey)
if encoder == nil {
typ := reflect2.TypeOf(val)
encoder = codec.EncoderOf(typ, defconf)
}
if encoderMapJson, ok := encoder.(codecore.IEncoderMapJson); !ok {
err = fmt.Errorf("val type:%T not support MarshalMapJson", val)
} else {
w := GetWriter()
ret, err = encoderMapJson.EncodeToMapJson(reflect2.PtrOf(val), w)
PutWriter(w)
}
return
}
func UnmarshalMap(data map[string]string, val interface{}) (err error) {
cacheKey := reflect2.RTypeOf(val)
decoder := codec.GetDecoder(cacheKey)
if decoder == nil {
typ := reflect2.TypeOf(val)
if typ == nil || typ.Kind() != reflect.Ptr {
err = errors.New("can only unmarshal into pointer")
return
}
decoder = codec.DecoderOf(typ, defconf)
}
ptr := reflect2.PtrOf(val)
if ptr == nil {
err = errors.New("can not read into nil pointer")
return
}
if decoderMapJson, ok := decoder.(codecore.IDecoderMapJson); !ok {
err = fmt.Errorf("val type:%T not support MarshalMapJson", val)
} else {
r := GetReader([]byte{})
err = decoderMapJson.DecodeForMapJson(ptr, r, data)
PutReader(r)
}
return
}
func MarshalSlice(val interface{}) (ret []string, err error) {
if nil == val {
err = errors.New("val is null")
return
}
cacheKey := reflect2.RTypeOf(val)
encoder := codec.GetEncoder(cacheKey)
if encoder == nil {
typ := reflect2.TypeOf(val)
encoder = codec.EncoderOf(typ, defconf)
}
if encoderMapJson, ok := encoder.(codecore.IEncoderSliceJson); !ok {
err = fmt.Errorf("val type:%T not support MarshalMapJson", val)
} else {
w := GetWriter()
ret, err = encoderMapJson.EncodeToSliceJson(reflect2.PtrOf(val), w)
w.PutWriter(w)
}
return
}
func UnmarshalSlice(data []string, val interface{}) (err error) {
cacheKey := reflect2.RTypeOf(val)
decoder := codec.GetDecoder(cacheKey)
if decoder == nil {
typ := reflect2.TypeOf(val)
if typ == nil || typ.Kind() != reflect.Ptr {
err = errors.New("can only unmarshal into pointer")
return
}
decoder = codec.DecoderOf(typ, defconf)
}
ptr := reflect2.PtrOf(val)
if ptr == nil {
err = errors.New("can not read into nil pointer")
return
}
if decoderMapJson, ok := decoder.(codecore.IDecoderSliceJson); !ok {
err = fmt.Errorf("val type:%T not support UnmarshalSliceJson", val)
} else {
r := GetReader([]byte{})
err = decoderMapJson.DecodeForSliceJson(ptr, r, data)
PutReader(r)
}
return
}

View File

@ -1,30 +1,21 @@
package render
package json
import (
"fmt"
"go_dreamfactory/lego/sys/codec/core"
"go_dreamfactory/lego/sys/codec/utils"
"io"
"math/big"
"reflect"
"unicode/utf16"
"go_dreamfactory/lego/utils/codec"
"go_dreamfactory/lego/utils/codec/codecore"
"go_dreamfactory/lego/utils/codec/utils"
"github.com/modern-go/reflect2"
)
func NewExtractor(codec core.ICodec) *JsonExtractor {
return &JsonExtractor{
codec: codec,
buf: nil,
head: 0,
tail: 0,
depth: 0,
err: nil,
}
}
type JsonExtractor struct {
codec core.ICodec
type JsonReader struct {
buf []byte
head int
tail int
@ -32,17 +23,29 @@ type JsonExtractor struct {
err error
}
func (this *JsonExtractor) ReadVal(obj interface{}) {
func (this *JsonReader) GetReader(buf []byte) codecore.IReader {
return GetReader(buf)
}
func (this *JsonReader) PutReader(r codecore.IReader) {
PutReader(r)
}
func (this *JsonReader) GetWriter() codecore.IWriter {
return GetWriter()
}
func (this *JsonReader) PutWriter(w codecore.IWriter) {
PutWriter(w)
}
func (this *JsonReader) ReadVal(obj interface{}) {
depth := this.depth
cacheKey := reflect2.RTypeOf(obj)
decoder := this.codec.GetDecoderFromCache(cacheKey)
decoder := codec.GetDecoder(cacheKey)
if decoder == nil {
typ := reflect2.TypeOf(obj)
if typ == nil || typ.Kind() != reflect.Ptr {
this.reportError("ReadVal", "can only unmarshal into pointer")
return
}
decoder = this.codec.DecoderOf(typ)
decoder = codec.DecoderOf(typ, defconf)
}
ptr := reflect2.PtrOf(obj)
if ptr == nil {
@ -55,35 +58,35 @@ func (this *JsonExtractor) ReadVal(obj interface{}) {
return
}
}
func (this *JsonExtractor) WhatIsNext() core.ValueType {
func (this *JsonReader) WhatIsNext() codecore.ValueType {
valueType := valueTypes[this.nextToken()]
this.unreadByte()
return valueType
}
func (this *JsonExtractor) Read() interface{} {
func (this *JsonReader) Read() interface{} {
valueType := this.WhatIsNext()
switch valueType {
case core.StringValue:
case codecore.StringValue:
return this.ReadString()
case core.NumberValue:
case codecore.NumberValue:
return this.ReadFloat64()
case core.NilValue:
case codecore.NilValue:
this.skipFourBytes('n', 'u', 'l', 'l')
return nil
case core.BoolValue:
case codecore.BoolValue:
return this.ReadBool()
case core.ArrayValue:
case codecore.ArrayValue:
arr := []interface{}{}
this.ReadArrayCB(func(extra core.IExtractor) bool {
this.ReadArrayCB(func(extra codecore.IReader) bool {
var elem interface{}
extra.ReadVal(&elem)
arr = append(arr, elem)
return true
})
return arr
case core.ObjectValue:
case codecore.ObjectValue:
obj := map[string]interface{}{}
this.ReadMapCB(func(extra core.IExtractor, field string) bool {
this.ReadMapCB(func(extra codecore.IReader, field string) bool {
var elem interface{}
this.ReadVal(&elem)
obj[field] = elem
@ -95,7 +98,7 @@ func (this *JsonExtractor) Read() interface{} {
return nil
}
}
func (this *JsonExtractor) ReadNil() (ret bool) {
func (this *JsonReader) ReadNil() (ret bool) {
c := this.nextToken()
if c == 'n' {
this.skipThreeBytes('u', 'l', 'l') // null
@ -104,7 +107,7 @@ func (this *JsonExtractor) ReadNil() (ret bool) {
this.unreadByte()
return false
}
func (this *JsonExtractor) ReadArrayStart() (ret bool) {
func (this *JsonReader) ReadArrayStart() (ret bool) {
c := this.nextToken()
if c == '[' {
return true
@ -112,7 +115,7 @@ func (this *JsonExtractor) ReadArrayStart() (ret bool) {
this.reportError("ReadArrayStart", `expect [ but found `+string([]byte{c}))
return
}
func (this *JsonExtractor) CheckNextIsArrayEnd() (ret bool) {
func (this *JsonReader) CheckNextIsArrayEnd() (ret bool) {
c := this.nextToken()
this.unreadByte()
if c == ']' {
@ -120,7 +123,7 @@ func (this *JsonExtractor) CheckNextIsArrayEnd() (ret bool) {
}
return
}
func (this *JsonExtractor) ReadArrayEnd() (ret bool) {
func (this *JsonReader) ReadArrayEnd() (ret bool) {
c := this.nextToken()
if c == ']' {
return true
@ -128,7 +131,7 @@ func (this *JsonExtractor) ReadArrayEnd() (ret bool) {
this.reportError("ReadArrayEnd", `expect ] but found `+string([]byte{c}))
return
}
func (this *JsonExtractor) ReadObjectStart() (ret bool) {
func (this *JsonReader) ReadObjectStart() (ret bool) {
c := this.nextToken()
if c == '{' {
return this.incrementDepth()
@ -136,7 +139,7 @@ func (this *JsonExtractor) ReadObjectStart() (ret bool) {
this.reportError("ReadObjectStart", `expect { but found `+string([]byte{c}))
return
}
func (this *JsonExtractor) CheckNextIsObjectEnd() (ret bool) {
func (this *JsonReader) CheckNextIsObjectEnd() (ret bool) {
c := this.nextToken()
this.unreadByte()
if c == '}' {
@ -144,7 +147,7 @@ func (this *JsonExtractor) CheckNextIsObjectEnd() (ret bool) {
}
return
}
func (this *JsonExtractor) ReadObjectEnd() (ret bool) {
func (this *JsonReader) ReadObjectEnd() (ret bool) {
c := this.nextToken()
if c == '}' {
return this.decrementDepth()
@ -152,7 +155,7 @@ func (this *JsonExtractor) ReadObjectEnd() (ret bool) {
this.reportError("ReadObjectEnd", `expect } but found `+string([]byte{c}))
return
}
func (this *JsonExtractor) ReadMemberSplit() (ret bool) {
func (this *JsonReader) ReadMemberSplit() (ret bool) {
c := this.nextToken()
if c == ',' {
return true
@ -160,7 +163,7 @@ func (this *JsonExtractor) ReadMemberSplit() (ret bool) {
this.unreadByte()
return
}
func (this *JsonExtractor) ReadKVSplit() (ret bool) {
func (this *JsonReader) ReadKVSplit() (ret bool) {
c := this.nextToken()
if c == ':' {
return true
@ -168,7 +171,7 @@ func (this *JsonExtractor) ReadKVSplit() (ret bool) {
this.reportError("ReadKVSplit", `expect : but found `+string([]byte{c}))
return
}
func (this *JsonExtractor) ReadKeyStart() (ret bool) {
func (this *JsonReader) ReadKeyStart() (ret bool) {
c := this.nextToken()
if c == '"' {
return true
@ -176,7 +179,7 @@ func (this *JsonExtractor) ReadKeyStart() (ret bool) {
this.reportError("ReadKeyStart", `expect " but found `+string([]byte{c}))
return
}
func (this *JsonExtractor) ReadKeyEnd() (ret bool) {
func (this *JsonReader) ReadKeyEnd() (ret bool) {
c := this.nextToken()
if c == '"' {
return true
@ -184,7 +187,7 @@ func (this *JsonExtractor) ReadKeyEnd() (ret bool) {
this.reportError("ReadKeyEnd", `expect " but found `+string([]byte{c}))
return
}
func (this *JsonExtractor) Skip() {
func (this *JsonReader) Skip() {
c := this.nextToken()
switch c {
case '"':
@ -209,7 +212,7 @@ func (this *JsonExtractor) Skip() {
return
}
}
func (this *JsonExtractor) ReadBool() (ret bool) {
func (this *JsonReader) ReadBool() (ret bool) {
c := this.nextToken()
if c == 't' {
this.skipThreeBytes('r', 'u', 'e')
@ -222,7 +225,7 @@ func (this *JsonExtractor) ReadBool() (ret bool) {
this.reportError("ReadBool", "expect t or f, but found "+string([]byte{c}))
return
}
func (this *JsonExtractor) ReadInt8() (ret int8) {
func (this *JsonReader) ReadInt8() (ret int8) {
var (
n int
err error
@ -234,7 +237,7 @@ func (this *JsonExtractor) ReadInt8() (ret int8) {
this.head += n
return
}
func (this *JsonExtractor) ReadInt16() (ret int16) {
func (this *JsonReader) ReadInt16() (ret int16) {
var (
n int
err error
@ -246,7 +249,7 @@ func (this *JsonExtractor) ReadInt16() (ret int16) {
this.head += n
return
}
func (this *JsonExtractor) ReadInt32() (ret int32) {
func (this *JsonReader) ReadInt32() (ret int32) {
var (
n int
err error
@ -258,7 +261,7 @@ func (this *JsonExtractor) ReadInt32() (ret int32) {
this.head += n
return
}
func (this *JsonExtractor) ReadInt64() (ret int64) {
func (this *JsonReader) ReadInt64() (ret int64) {
var (
n int
err error
@ -270,7 +273,7 @@ func (this *JsonExtractor) ReadInt64() (ret int64) {
this.head += n
return
}
func (this *JsonExtractor) ReadUint8() (ret uint8) {
func (this *JsonReader) ReadUint8() (ret uint8) {
var (
n int
err error
@ -282,7 +285,7 @@ func (this *JsonExtractor) ReadUint8() (ret uint8) {
this.head += n
return
}
func (this *JsonExtractor) ReadUint16() (ret uint16) {
func (this *JsonReader) ReadUint16() (ret uint16) {
var (
n int
err error
@ -294,7 +297,7 @@ func (this *JsonExtractor) ReadUint16() (ret uint16) {
this.head += n
return
}
func (this *JsonExtractor) ReadUint32() (ret uint32) {
func (this *JsonReader) ReadUint32() (ret uint32) {
var (
n int
err error
@ -306,7 +309,7 @@ func (this *JsonExtractor) ReadUint32() (ret uint32) {
this.head += n
return
}
func (this *JsonExtractor) ReadUint64() (ret uint64) {
func (this *JsonReader) ReadUint64() (ret uint64) {
var (
n int
err error
@ -318,7 +321,7 @@ func (this *JsonExtractor) ReadUint64() (ret uint64) {
this.head += n
return
}
func (this *JsonExtractor) ReadFloat32() (ret float32) {
func (this *JsonReader) ReadFloat32() (ret float32) {
var (
n int
err error
@ -330,7 +333,7 @@ func (this *JsonExtractor) ReadFloat32() (ret float32) {
this.head += n
return
}
func (this *JsonExtractor) ReadFloat64() (ret float64) {
func (this *JsonReader) ReadFloat64() (ret float64) {
var (
n int
err error
@ -342,7 +345,7 @@ func (this *JsonExtractor) ReadFloat64() (ret float64) {
this.head += n
return
}
func (this *JsonExtractor) ReadString() (ret string) {
func (this *JsonReader) ReadString() (ret string) {
c := this.nextToken()
if c == '"' {
for i := this.head; i < this.tail; i++ {
@ -367,20 +370,20 @@ func (this *JsonExtractor) ReadString() (ret string) {
this.reportError("ReadString", `expects " or n, but found `+string([]byte{c}))
return
}
func (this *JsonExtractor) ResetBytes(d []byte) {
func (this *JsonReader) ResetBytes(d []byte) {
this.buf = d
this.head = 0
this.tail = len(d)
}
func (this *JsonExtractor) Error() error {
func (this *JsonReader) Error() error {
return this.err
}
func (this *JsonExtractor) SetErr(err error) {
func (this *JsonReader) SetErr(err error) {
this.err = err
}
//-----------------------------------------------------------------------------------------------------------------------------------
func (this *JsonExtractor) readByte() (ret byte) {
func (this *JsonReader) readByte() (ret byte) {
if this.head == this.tail {
return 0
}
@ -388,7 +391,7 @@ func (this *JsonExtractor) readByte() (ret byte) {
this.head++
return ret
}
func (this *JsonExtractor) readStringSlowPath() (ret string) {
func (this *JsonReader) readStringSlowPath() (ret string) {
var str []byte
var c byte
for this.err == nil {
@ -406,7 +409,7 @@ func (this *JsonExtractor) readStringSlowPath() (ret string) {
this.reportError("readStringSlowPath", "unexpected end of input")
return
}
func (this *JsonExtractor) readEscapedChar(c byte, str []byte) []byte {
func (this *JsonReader) readEscapedChar(c byte, str []byte) []byte {
switch c {
case 'u':
r := this.readU4()
@ -465,7 +468,7 @@ func (this *JsonExtractor) readEscapedChar(c byte, str []byte) []byte {
}
return str
}
func (this *JsonExtractor) readU4() (ret rune) {
func (this *JsonReader) readU4() (ret rune) {
for i := 0; i < 4; i++ {
c := this.readByte()
if this.err != nil {
@ -484,7 +487,7 @@ func (this *JsonExtractor) readU4() (ret rune) {
}
return ret
}
func (this *JsonExtractor) nextToken() byte {
func (this *JsonReader) nextToken() byte {
for i := this.head; i < this.tail; i++ {
c := this.buf[i]
switch c {
@ -496,14 +499,14 @@ func (this *JsonExtractor) nextToken() byte {
}
return 0
}
func (this *JsonExtractor) unreadByte() {
func (this *JsonReader) unreadByte() {
if this.err != nil {
return
}
this.head--
return
}
func (this *JsonExtractor) skipNumber() {
func (this *JsonReader) skipNumber() {
if !this.trySkipNumber() {
this.unreadByte()
if this.err != nil && this.err != io.EOF {
@ -516,7 +519,7 @@ func (this *JsonExtractor) skipNumber() {
}
}
}
func (this *JsonExtractor) ReadBigFloat() (ret *big.Float) {
func (this *JsonReader) ReadBigFloat() (ret *big.Float) {
var (
n int
err error
@ -528,7 +531,7 @@ func (this *JsonExtractor) ReadBigFloat() (ret *big.Float) {
this.head += n
return
}
func (iter *JsonExtractor) trySkipNumber() bool {
func (iter *JsonReader) trySkipNumber() bool {
dotFound := false
for i := iter.head; i < iter.tail; i++ {
c := iter.buf[i]
@ -564,13 +567,13 @@ func (iter *JsonExtractor) trySkipNumber() bool {
}
return false
}
func (this *JsonExtractor) skipString() {
func (this *JsonReader) skipString() {
if !this.trySkipString() {
this.unreadByte()
this.ReadString()
}
}
func (this *JsonExtractor) trySkipString() bool {
func (this *JsonReader) trySkipString() bool {
for i := this.head; i < this.tail; i++ {
c := this.buf[i]
if c == '"' {
@ -586,21 +589,21 @@ func (this *JsonExtractor) trySkipString() bool {
}
return false
}
func (this *JsonExtractor) skipObject() {
func (this *JsonReader) skipObject() {
this.unreadByte()
this.ReadObjectCB(func(extra core.IExtractor, field string) bool {
this.ReadObjectCB(func(extra codecore.IReader, field string) bool {
extra.Skip()
return true
})
}
func (this *JsonExtractor) skipArray() {
func (this *JsonReader) skipArray() {
this.unreadByte()
this.ReadArrayCB(func(extra core.IExtractor) bool {
this.ReadArrayCB(func(extra codecore.IReader) bool {
extra.Skip()
return true
})
}
func (this *JsonExtractor) skipThreeBytes(b1, b2, b3 byte) {
func (this *JsonReader) skipThreeBytes(b1, b2, b3 byte) {
if this.readByte() != b1 {
this.reportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
return
@ -614,7 +617,7 @@ func (this *JsonExtractor) skipThreeBytes(b1, b2, b3 byte) {
return
}
}
func (this *JsonExtractor) skipFourBytes(b1, b2, b3, b4 byte) {
func (this *JsonReader) skipFourBytes(b1, b2, b3, b4 byte) {
if this.readByte() != b1 {
this.reportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
return
@ -632,7 +635,7 @@ func (this *JsonExtractor) skipFourBytes(b1, b2, b3, b4 byte) {
return
}
}
func (this *JsonExtractor) reportError(operation string, msg string) {
func (this *JsonReader) reportError(operation string, msg string) {
if this.err != nil {
if this.err != io.EOF {
return
@ -659,7 +662,7 @@ func (this *JsonExtractor) reportError(operation string, msg string) {
this.err = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...",
operation, msg, this.head-peekStart, parsing, context)
}
func (this *JsonExtractor) incrementDepth() (success bool) {
func (this *JsonReader) incrementDepth() (success bool) {
this.depth++
if this.depth <= maxDepth {
return true
@ -667,7 +670,7 @@ func (this *JsonExtractor) incrementDepth() (success bool) {
this.reportError("incrementDepth", "exceeded max depth")
return false
}
func (this *JsonExtractor) decrementDepth() (success bool) {
func (this *JsonReader) decrementDepth() (success bool) {
this.depth--
if this.depth >= 0 {
return true
@ -675,7 +678,7 @@ func (this *JsonExtractor) decrementDepth() (success bool) {
this.reportError("decrementDepth", "unexpected negative nesting")
return false
}
func (iter *JsonExtractor) ReadObjectCB(callback func(core.IExtractor, string) bool) bool {
func (iter *JsonReader) ReadObjectCB(callback func(codecore.IReader, string) bool) bool {
c := iter.nextToken()
var field string
if c == '{' {
@ -729,7 +732,7 @@ func (iter *JsonExtractor) ReadObjectCB(callback func(core.IExtractor, string) b
return false
}
func (iter *JsonExtractor) ReadMapCB(callback func(core.IExtractor, string) bool) bool {
func (iter *JsonReader) ReadMapCB(callback func(codecore.IReader, string) bool) bool {
c := iter.nextToken()
if c == '{' {
if !iter.incrementDepth() {
@ -784,7 +787,7 @@ func (iter *JsonExtractor) ReadMapCB(callback func(core.IExtractor, string) bool
return false
}
func (iter *JsonExtractor) ReadArrayCB(callback func(core.IExtractor) bool) (ret bool) {
func (iter *JsonReader) ReadArrayCB(callback func(codecore.IReader) bool) (ret bool) {
c := iter.nextToken()
if c == '[' {
if !iter.incrementDepth() {

View File

@ -0,0 +1,216 @@
package json
import (
"go_dreamfactory/lego/utils/codec"
"go_dreamfactory/lego/utils/codec/codecore"
"go_dreamfactory/lego/utils/codec/utils"
"github.com/modern-go/reflect2"
)
const indentionStep = 1
type JsonWriter struct {
err error
buf []byte
indention int
}
func (this *JsonWriter) GetReader(buf []byte) codecore.IReader {
return GetReader(buf)
}
func (this *JsonWriter) PutReader(r codecore.IReader) {
PutReader(r)
}
func (this *JsonWriter) GetWriter() codecore.IWriter {
return GetWriter()
}
func (this *JsonWriter) PutWriter(w codecore.IWriter) {
PutWriter(w)
}
//写入对象
func (this *JsonWriter) WriteVal(val interface{}) {
if nil == val {
this.WriteNil()
return
}
cacheKey := reflect2.RTypeOf(val)
encoder := codec.GetEncoder(cacheKey)
if encoder == nil {
typ := reflect2.TypeOf(val)
encoder = codec.EncoderOf(typ, defconf)
}
encoder.Encode(reflect2.PtrOf(val), this)
}
func (this *JsonWriter) WriteNil() {
this.writeFourBytes('n', 'u', 'l', 'l')
}
func (this *JsonWriter) WriteEmptyArray() {
this.writeTwoBytes('[', ']')
}
func (this *JsonWriter) WriteArrayStart() {
this.indention += indentionStep
this.writeByte('[')
this.writeIndention(0)
}
func (this *JsonWriter) WriteArrayEnd() {
this.writeIndention(indentionStep)
this.indention -= indentionStep
this.writeByte(']')
}
func (this *JsonWriter) WriteEmptyObject() {
this.writeTwoBytes('{', '}')
}
func (this *JsonWriter) WriteObjectStart() {
this.indention += indentionStep
this.writeByte('{')
this.writeIndention(0)
}
func (this *JsonWriter) WriteObjectEnd() {
this.writeIndention(indentionStep)
this.indention -= indentionStep
this.writeByte('}')
}
func (this *JsonWriter) WriteMemberSplit() {
this.writeByte(',')
this.writeIndention(0)
}
func (this *JsonWriter) WriteKVSplit() {
this.writeByte(':')
}
func (this *JsonWriter) WriteKeyStart() {
this.writeByte('"')
}
func (this *JsonWriter) WriteKeyEnd() {
this.writeByte('"')
}
func (this *JsonWriter) WriteObjectFieldName(val string) {
this.WriteString(val)
if this.indention > 0 {
this.writeTwoBytes(':', ' ')
} else {
this.writeByte(':')
}
}
func (this *JsonWriter) WriteBool(val bool) {
if val {
this.writeTrue()
} else {
this.writeFalse()
}
}
func (this *JsonWriter) WriteInt8(val int8) {
utils.WriteInt8ToString(&this.buf, val)
}
func (this *JsonWriter) WriteInt16(val int16) {
utils.WriteInt16ToString(&this.buf, val)
}
func (this *JsonWriter) WriteInt32(val int32) {
utils.WriteInt32ToString(&this.buf, val)
}
func (this *JsonWriter) WriteInt64(val int64) {
utils.WriteInt64ToString(&this.buf, val)
}
func (this *JsonWriter) WriteUint8(val uint8) {
utils.WriteUint8ToString(&this.buf, val)
}
func (this *JsonWriter) WriteUint16(val uint16) {
utils.WriteUint16ToString(&this.buf, val)
}
func (this *JsonWriter) WriteUint32(val uint32) {
utils.WriteUint32ToString(&this.buf, val)
}
func (this *JsonWriter) WriteUint64(val uint64) {
utils.WriteUint64ToString(&this.buf, val)
}
func (this *JsonWriter) WriteFloat32(val float32) {
utils.WriteFloat32ToString(&this.buf, val)
}
func (this *JsonWriter) WriteFloat64(val float64) {
utils.WriteFloat64ToString(&this.buf, val)
}
func (this *JsonWriter) WriteString(val string) {
valLen := len(val)
this.buf = append(this.buf, '"')
i := 0
for ; i < valLen; i++ {
c := val[i]
if c > 31 && c != '"' && c != '\\' {
this.buf = append(this.buf, c)
} else {
break
}
}
if i == valLen {
this.buf = append(this.buf, '"')
return
}
utils.WriteStringSlowPath(&this.buf, i, val, valLen)
}
func (this *JsonWriter) WriteBytes(val []byte) {
this.buf = append(this.buf, val...)
}
func (this *JsonWriter) Reset() {
this.buf = this.buf[:0]
this.err = nil
this.indention = 0
return
}
func (this *JsonWriter) Buffer() []byte {
return this.buf
}
func (this *JsonWriter) Buffered() int {
return len(this.buf)
}
func (this *JsonWriter) Error() error {
return this.err
}
func (this *JsonWriter) SetErr(err error) {
this.err = err
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------
// WriteTrue write true to stream
func (stream *JsonWriter) writeTrue() {
stream.writeFourBytes('t', 'r', 'u', 'e')
}
// WriteFalse write false to stream
func (stream *JsonWriter) writeFalse() {
stream.writeFiveBytes('f', 'a', 'l', 's', 'e')
}
func (this *JsonWriter) writeByte(c byte) {
this.buf = append(this.buf, c)
}
func (this *JsonWriter) writeTwoBytes(c1 byte, c2 byte) {
this.buf = append(this.buf, c1, c2)
}
func (this *JsonWriter) writeThreeBytes(c1 byte, c2 byte, c3 byte) {
this.buf = append(this.buf, c1, c2, c3)
}
func (this *JsonWriter) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) {
this.buf = append(this.buf, c1, c2, c3, c4)
}
func (this *JsonWriter) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) {
this.buf = append(this.buf, c1, c2, c3, c4, c5)
}
func (stream *JsonWriter) writeIndention(delta int) {
if stream.indention == 0 {
return
}
stream.writeByte('\n')
toWrite := stream.indention - delta
for i := 0; i < toWrite; i++ {
stream.buf = append(stream.buf, ' ')
}
}

View File

@ -0,0 +1,31 @@
package codec
import "strconv"
func Atoi(b []byte) (int, error) {
return strconv.Atoi(BytesToString(b))
}
func ParseInt(b []byte, base int, bitSize int) (int64, error) {
return strconv.ParseInt(BytesToString(b), base, bitSize)
}
func ParseUint(b []byte, base int, bitSize int) (uint64, error) {
return strconv.ParseUint(BytesToString(b), base, bitSize)
}
func ParseFloat(b []byte, bitSize int) (float64, error) {
return strconv.ParseFloat(BytesToString(b), bitSize)
}
func UintToString(n uint64) string {
return BytesToString(strconv.AppendUint([]byte{}, n, 10))
}
func IntToString(n int64) string {
return BytesToString(strconv.AppendInt([]byte{}, n, 10))
}
func FloatToString(f float64) string {
return BytesToString(strconv.AppendFloat([]byte{}, f, 'f', -1, 64))
}

View File

@ -0,0 +1,136 @@
package pools
import (
"io"
"strconv"
"sync"
"time"
)
/*
bytes buffer 缓存池
*/
const _size = 1024
var bufferPool = &BufferPool{p: &sync.Pool{
New: func() interface{} {
return &Buffer{bs: make([]byte, 0, _size)}
},
}}
func BufferPoolGet() *Buffer {
return bufferPool.get()
}
func BufferPoolPut(buf *Buffer) {
bufferPool.put(buf)
}
type BufferPool struct {
p *sync.Pool
}
func (p BufferPool) get() *Buffer {
buf := p.p.Get().(*Buffer)
buf.reset()
buf.pool = p
return buf
}
func (p BufferPool) put(buf *Buffer) {
p.p.Put(buf)
}
type Buffer struct {
bs []byte
pool BufferPool
}
func (b *Buffer) reset() {
b.bs = b.bs[:0]
}
func (b *Buffer) Len() int {
return len(b.bs)
}
func (b *Buffer) Cap() int {
return cap(b.bs)
}
func (b *Buffer) Bytes() []byte {
return b.bs
}
func (b *Buffer) String() string {
return string(b.bs)
}
func (b *Buffer) ReadFrom(r io.Reader) (int64, error) {
p := b.bs
nStart := int64(len(p))
nMax := int64(cap(p))
n := nStart
if nMax == 0 {
nMax = 64
p = make([]byte, nMax)
} else {
p = p[:nMax]
}
for {
if n == nMax {
nMax *= 2
bNew := make([]byte, nMax)
copy(bNew, p)
p = bNew
}
nn, err := r.Read(p[n:])
n += int64(nn)
if err != nil {
b.bs = p[:n]
n -= nStart
if err == io.EOF {
return n, nil
}
return n, err
}
}
}
func (b *Buffer) AppendByte(v byte) {
b.bs = append(b.bs, v)
}
func (b *Buffer) AppendInt(i int64) {
b.bs = strconv.AppendInt(b.bs, i, 10)
}
func (b *Buffer) AppendUint(i uint64) {
b.bs = strconv.AppendUint(b.bs, i, 10)
}
func (b *Buffer) AppendFloat(f float64, bitSize int) {
b.bs = strconv.AppendFloat(b.bs, f, 'f', -1, bitSize)
}
func (b *Buffer) AppendBool(v bool) {
b.bs = strconv.AppendBool(b.bs, v)
}
func (b *Buffer) AppendTime(t time.Time, layout string) {
b.bs = t.AppendFormat(b.bs, layout)
}
func (b *Buffer) AppendString(s string) {
b.bs = append(b.bs, s...)
}
func (b *Buffer) AppendBytes(s []byte) {
b.bs = append(b.bs, s...)
}
func (b *Buffer) Write(p []byte) (int, error) {
b.bs = append(b.bs, p...)
return len(p), nil
}
func (b *Buffer) WriteString(s string) (int, error) {
b.AppendString(s)
return len(s), nil
}
func (b *Buffer) WriteByte(v byte) error {
b.AppendByte(v)
return nil
}
func (b *Buffer) WriteTo(w io.Writer) (int64, error) {
n, err := w.Write(b.bs)
return int64(n), err
}
func (b *Buffer) Free() {
b.pool.put(b)
}

View File

@ -5,8 +5,8 @@ import (
"fmt"
"go_dreamfactory/comm"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/codec"
"go_dreamfactory/lego/sys/redis"
"go_dreamfactory/lego/utils/codec/json"
"go_dreamfactory/modules"
"go_dreamfactory/pb"
@ -101,7 +101,7 @@ func (this *modelChatComp) GetChatQueue(channel pb.ChatChannel, union, group, ar
result = make([]*pb.DBChat, len(cdata))
for i, v := range cdata {
chat := &pb.DBChat{}
if err = codec.UnmarshalMapJson(v, chat); err != nil {
if err = json.UnmarshalMap(v, chat); err != nil {
return
}
result[i] = chat
@ -256,7 +256,7 @@ func (this *modelChatComp) addChatMsg(key string, count int32, msgs ...*pb.DBCha
vs = make([]map[string]string, len(msgs))
values = make([]interface{}, len(msgs))
for i, v := range msgs {
if tempdata, err = codec.MarshalMapJson(v); err != nil {
if tempdata, err = json.MarshalMap(v); err != nil {
this.module.Errorf("err:%v", err)
return
}

View File

@ -6,11 +6,12 @@ import (
"go_dreamfactory/comm"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/core/cbase"
"go_dreamfactory/lego/sys/codec"
ccore "go_dreamfactory/lego/sys/codec/core"
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/lego/sys/mgo"
"go_dreamfactory/lego/sys/redis"
"go_dreamfactory/lego/utils/codec"
"go_dreamfactory/lego/utils/codec/codecore"
"go_dreamfactory/lego/utils/codec/json"
"go_dreamfactory/sys/cache"
"go_dreamfactory/sys/db"
"reflect"
@ -22,6 +23,15 @@ import (
"go.mongodb.org/mongo-driver/mongo"
)
var defconf = &codecore.Config{
SortMapKeys: true,
IndentionStep: 1,
OnlyTaggedField: false,
DisallowUnknownFields: false,
CaseSensitive: false,
TagKey: "json",
}
//Redis 自定义脚本 批量读取列表数据
var LuaScriptgetList = `
local key = tostring(KEYS[1])
@ -374,8 +384,8 @@ func (this *MCompModel) GetList(uid string, data interface{}) (err error) {
sType reflect2.Type
sliceType *reflect2.UnsafeSliceType
sliceelemType reflect2.Type
decoder ccore.IDecoderMapJson
encoder ccore.IEncoderMapJson
decoder codecore.IDecoderMapJson
encoder codecore.IEncoderMapJson
dptr unsafe.Pointer
elemPtr unsafe.Pointer
n int
@ -405,7 +415,7 @@ func (this *MCompModel) GetList(uid string, data interface{}) (err error) {
err = fmt.Errorf("MCompModel: GetList(sliceelemType non-pointer %T)", data)
return
}
if decoder, ok = codec.DecoderOf(sliceelemType).(ccore.IDecoderMapJson); !ok {
if decoder, ok = codec.DecoderOf(sliceelemType, defconf).(codecore.IDecoderMapJson); !ok {
err = fmt.Errorf("MCompModel: GetList(data not support MarshalMapJson %T)", data)
return
}
@ -416,13 +426,13 @@ func (this *MCompModel) GetList(uid string, data interface{}) (err error) {
elemPtr = sliceType.UnsafeGetIndex(dptr, n)
if *((*unsafe.Pointer)(elemPtr)) == nil {
newPtr := sliceelemType.UnsafeNew()
if err = decoder.DecodeForMapJson(newPtr, v); err != nil {
if err = decoder.DecodeForMapJson(newPtr, json.GetReader([]byte{}), v); err != nil {
log.Errorf("err:%v", err)
return
}
*((*unsafe.Pointer)(elemPtr)) = newPtr
} else {
decoder.DecodeForMapJson(*((*unsafe.Pointer)(elemPtr)), v)
decoder.DecodeForMapJson(*((*unsafe.Pointer)(elemPtr)), json.GetReader([]byte{}), v)
}
n++
}
@ -432,7 +442,7 @@ func (this *MCompModel) GetList(uid string, data interface{}) (err error) {
if c, err = this.DB.Find(core.SqlTable(this.TableName), bson.M{"uid": uid}); err != nil {
return err
} else {
if encoder, ok = codec.EncoderOf(sliceelemType).(ccore.IEncoderMapJson); !ok {
if encoder, ok = codec.EncoderOf(sliceelemType, defconf).(codecore.IEncoderMapJson); !ok {
err = fmt.Errorf("MCompModel: GetList(data not support UnMarshalMapJson %T)", data)
return
}
@ -450,7 +460,7 @@ func (this *MCompModel) GetList(uid string, data interface{}) (err error) {
if err = c.Decode(elem); err != nil {
return
}
if tempdata, err = encoder.EncodeToMapJson(*((*unsafe.Pointer)(elemPtr))); err != nil {
if tempdata, err = encoder.EncodeToMapJson(*((*unsafe.Pointer)(elemPtr)), json.GetWriter()); err != nil {
return
}
key := this.ukeylist(uid, _id)
@ -668,33 +678,6 @@ func (this *MCompModel) logOpt(uid string, data interface{}, attrs ...*cache.Ope
return nil
}
//获取用户通过扩展表
// func (this *MCompModel) GetUserRecord(uid string) (result *pb.DBUserRecord, err error) {
// result = &pb.DBUserRecord{}
// key := fmt.Sprintf("userrecord:%s{userrecord}", uid)
// if err = this.Redis.HGetAll(key, result); err != nil && err != redis.RedisNil {
// return
// }
// if err == redis.RedisNil {
// if err = this.DB.FindOne(core.SqlTable("userrecord"), bson.M{"uid": uid}).Decode(result); err != nil {
// return
// }
// err = this.Redis.HMSet(key, result)
// }
// return
// }
// //修改用户扩展数据
// func (this *MCompModel) ChangeUserRecord(uid string, value map[string]interface{}) (err error) {
// value["mtime"] = time.Now().Unix() // 更新时间
// key := fmt.Sprintf("userrecord:%s{userrecord}", uid)
// if err = this.Redis.HMSet(key, value); err != nil && err != redis.RedisNil {
// return
// }
// err = this.UpdateModelLogs("userrecord", uid, bson.M{"uid": uid}, value)
// return
// }
// 删除玩家缓存信息
func (this *MCompModel) CleanUserRecord(uid string) (err error) {
err = this.Redis.Delete(this.ukey(uid))

View File

@ -1,7 +1,6 @@
package gateway
import (
"fmt"
"go_dreamfactory/comm"
"go_dreamfactory/lego/base"
@ -103,33 +102,69 @@ func (this *Gateway) GetMsgDistribute(mtype, stype string) (rule string, ok bool
}
//日志
func (this *Gateway) Debugf(format string, a ...interface{}) {
if this.options.GetDebug() {
this.options.GetLog().Debugf(fmt.Sprintf("[Module:%s] ", this.GetType())+format, a...)
}
//日志接口
func (this *Gateway) Debug(msg string, args ...log.Field) {
this.options.GetLog().Debug(msg, args...)
}
func (this *Gateway) Infof(format string, a ...interface{}) {
if this.options.GetDebug() {
this.options.GetLog().Infof(fmt.Sprintf("[Module:%s] ", this.GetType())+format, a...)
}
func (this *Gateway) Info(msg string, args ...log.Field) {
this.options.GetLog().Info(msg, args...)
}
func (this *Gateway) Warnf(format string, a ...interface{}) {
if this.options.Debug {
this.options.GetLog().Warnf(fmt.Sprintf("[Module:%s] ", this.GetType())+format, a...)
}
func (this *Gateway) Print(msg string, args ...log.Field) {
this.options.GetLog().Print(msg, args...)
}
func (this *Gateway) Errorf(format string, a ...interface{}) {
if this.options.GetLog() != nil {
this.options.GetLog().Errorf(fmt.Sprintf("[Module:%s] ", this.GetType())+format, a...)
}
func (this *Gateway) Warn(msg string, args ...log.Field) {
this.options.GetLog().Warn(msg, args...)
}
func (this *Gateway) Panicf(format string, a ...interface{}) {
if this.options.GetLog() != nil {
this.options.GetLog().Panicf(fmt.Sprintf("[Module:%s] ", this.GetType())+format, a...)
}
func (this *Gateway) Error(msg string, args ...log.Field) {
this.options.GetLog().Error(msg, args...)
}
func (this *Gateway) Fatalf(format string, a ...interface{}) {
if this.options.GetLog() != nil {
this.options.GetLog().Fatalf(fmt.Sprintf("[Module:%s] ", this.GetType())+format, a...)
}
func (this *Gateway) Panic(msg string, args ...log.Field) {
this.options.GetLog().Panic(msg, args...)
}
func (this *Gateway) Fatal(msg string, args ...log.Field) {
this.options.GetLog().Fatal(msg, args...)
}
func (this *Gateway) Debugf(format string, args ...interface{}) {
this.options.GetLog().Debugf(format, args...)
}
func (this *Gateway) Infof(format string, args ...interface{}) {
this.options.GetLog().Infof(format, args...)
}
func (this *Gateway) Printf(format string, args ...interface{}) {
this.options.GetLog().Printf(format, args...)
}
func (this *Gateway) Warnf(format string, args ...interface{}) {
this.options.GetLog().Warnf(format, args...)
}
func (this *Gateway) Errorf(format string, args ...interface{}) {
this.options.GetLog().Errorf(format, args...)
}
func (this *Gateway) Fatalf(format string, args ...interface{}) {
this.options.GetLog().Fatalf(format, args...)
}
func (this *Gateway) Panicf(format string, args ...interface{}) {
this.options.GetLog().Panicf(format, args...)
}
func (this *Gateway) Debugln(args ...interface{}) {
this.options.GetLog().Debugln(args...)
}
func (this *Gateway) Infoln(args ...interface{}) {
this.options.GetLog().Infoln(args...)
}
func (this *Gateway) Println(args ...interface{}) {
this.options.GetLog().Println(args...)
}
func (this *Gateway) Warnln(args ...interface{}) {
this.options.GetLog().Warnln(args...)
}
func (this *Gateway) Errorln(args ...interface{}) {
this.options.GetLog().Errorln(args...)
}
func (this *Gateway) Fatalln(args ...interface{}) {
this.options.GetLog().Fatalln(args...)
}
func (this *Gateway) Panicln(args ...interface{}) {
this.options.GetLog().Panicln(args...)
}

View File

@ -43,6 +43,7 @@ func (this *ModuleBase) Init(service core.IService, module core.IModule, options
this.service = service.(base.IRPCXService)
this.module = module
this.options = options.(IOptions)
this.options.GetLog().SetName("module." + string(module.GetType()))
return
}
@ -289,33 +290,68 @@ func (this *ModuleBase) DispenseRes(session comm.IUserSession, res []*cfg.Game_a
}
//日志接口
func (this *ModuleBase) Debugf(format string, a ...interface{}) {
if this.options.GetDebug() {
this.options.GetLog().Debugf(fmt.Sprintf("[Module:%s] ", this.module.GetType())+format, a...)
}
func (this *ModuleBase) Debug(msg string, args ...log.Field) {
this.options.GetLog().Debug(msg, args...)
}
func (this *ModuleBase) Infof(format string, a ...interface{}) {
if this.options.GetDebug() {
this.options.GetLog().Infof(fmt.Sprintf("[Module:%s] ", this.module.GetType())+format, a...)
}
func (this *ModuleBase) Info(msg string, args ...log.Field) {
this.options.GetLog().Info(msg, args...)
}
func (this *ModuleBase) Warnf(format string, a ...interface{}) {
if this.options.GetDebug() {
this.options.GetLog().Warnf(fmt.Sprintf("[Module:%s] ", this.module.GetType())+format, a...)
}
func (this *ModuleBase) Print(msg string, args ...log.Field) {
this.options.GetLog().Print(msg, args...)
}
func (this *ModuleBase) Errorf(format string, a ...interface{}) {
if this.options.GetLog() != nil {
this.options.GetLog().Errorf(fmt.Sprintf("[Module:%s] ", this.module.GetType())+format, a...)
}
func (this *ModuleBase) Warn(msg string, args ...log.Field) {
this.options.GetLog().Warn(msg, args...)
}
func (this *ModuleBase) Panicf(format string, a ...interface{}) {
if this.options.GetLog() != nil {
this.options.GetLog().Panicf(fmt.Sprintf("[Module:%s] ", this.module.GetType())+format, a...)
}
func (this *ModuleBase) Error(msg string, args ...log.Field) {
this.options.GetLog().Error(msg, args...)
}
func (this *ModuleBase) Fatalf(format string, a ...interface{}) {
if this.options.GetLog() != nil {
this.options.GetLog().Fatalf(fmt.Sprintf("[Module:%s] ", this.module.GetType())+format, a...)
}
func (this *ModuleBase) Panic(msg string, args ...log.Field) {
this.options.GetLog().Panic(msg, args...)
}
func (this *ModuleBase) Fatal(msg string, args ...log.Field) {
this.options.GetLog().Fatal(msg, args...)
}
func (this *ModuleBase) Debugf(format string, args ...interface{}) {
this.options.GetLog().Debugf(format, args...)
}
func (this *ModuleBase) Infof(format string, args ...interface{}) {
this.options.GetLog().Infof(format, args...)
}
func (this *ModuleBase) Printf(format string, args ...interface{}) {
this.options.GetLog().Printf(format, args...)
}
func (this *ModuleBase) Warnf(format string, args ...interface{}) {
this.options.GetLog().Warnf(format, args...)
}
func (this *ModuleBase) Errorf(format string, args ...interface{}) {
this.options.GetLog().Errorf(format, args...)
}
func (this *ModuleBase) Fatalf(format string, args ...interface{}) {
this.options.GetLog().Fatalf(format, args...)
}
func (this *ModuleBase) Panicf(format string, args ...interface{}) {
this.options.GetLog().Panicf(format, args...)
}
func (this *ModuleBase) Debugln(args ...interface{}) {
this.options.GetLog().Debugln(args...)
}
func (this *ModuleBase) Infoln(args ...interface{}) {
this.options.GetLog().Infoln(args...)
}
func (this *ModuleBase) Println(args ...interface{}) {
this.options.GetLog().Println(args...)
}
func (this *ModuleBase) Warnln(args ...interface{}) {
this.options.GetLog().Warnln(args...)
}
func (this *ModuleBase) Errorln(args ...interface{}) {
this.options.GetLog().Errorln(args...)
}
func (this *ModuleBase) Fatalln(args ...interface{}) {
this.options.GetLog().Fatalln(args...)
}
func (this *ModuleBase) Panicln(args ...interface{}) {
this.options.GetLog().Panicln(args...)
}

View File

@ -1,7 +1,7 @@
package modules
import (
"fmt"
"errors"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/lego/utils/mapstructure"
@ -12,11 +12,11 @@ type (
IOptions interface {
core.IModuleOptions
GetDebug() bool
GetLog() log.ILog
GetLog() log.ILogger
}
Options struct {
Debug bool //日志是否开启
Log log.ILog
Log log.ILogger
}
)
@ -24,7 +24,7 @@ func (this *Options) GetDebug() bool {
return this.Debug
}
func (this *Options) GetLog() log.ILog {
func (this *Options) GetLog() log.ILogger {
return this.Log
}
@ -32,12 +32,9 @@ func (this *Options) LoadConfig(settings map[string]interface{}) (err error) {
if settings != nil {
err = mapstructure.Decode(settings, this)
}
if this.Debug && this.Log == nil {
this.Log = log.Clone()
if this.Log == nil {
err = fmt.Errorf("Log is nil")
return
}
if this.Log = log.NewTurnlog(this.Debug, log.Clone("", 2)); this.Log == nil {
err = errors.New("log is nil")
}
return
}

View File

@ -153,11 +153,25 @@ func (this *SCompGateRoute) ReceiveMsg(ctx context.Context, args *pb.AgentMessag
data, _ := anypb.New(errdata.(proto.Message))
reply.ErrorData = data
}
log.Errorf("[Handle Api] t:%v m:%s req:%v reply:%v", time.Since(stime), method, msg, reply)
// log.Errorf("[Handle Api] t:%v m:%s req:%v reply:%v", time.Since(stime), method, msg, reply)
log.Error("[Handle Api]",
log.Field{Key: "t", Value: time.Since(stime)},
log.Field{Key: "m", Value: method},
log.Field{Key: "uid", Value: args.UserId},
log.Field{Key: "req", Value: msg},
log.Field{Key: "reply", Value: reply},
)
} else {
reply.Reply = session.Polls()
if this.options.Debug {
log.Debugf("[Handle Api] t:%v m:%s uid:%s req:%v reply:%v", time.Since(stime), method, args.UserId, msg, reply)
// log.Debugf("[Handle Api] t:%v m:%s uid:%s req:%v reply:%v", time.Since(stime), method, args.UserId, msg, reply)
log.Debug("[Handle Api]",
log.Field{Key: "t", Value: time.Since(stime)},
log.Field{Key: "m", Value: method},
log.Field{Key: "uid", Value: args.UserId},
log.Field{Key: "req", Value: msg},
log.Field{Key: "reply", Value: reply},
)
}
}
} else { //未找到消息处理函数

37
services/service_test.go Normal file
View File

@ -0,0 +1,37 @@
package services_test
import (
"fmt"
"go_dreamfactory/lego/sys/log"
"os"
"testing"
)
type TestData struct {
Name string
Age int32
}
func (this *TestData) Log() {
sys.Error("妈妈咪呀!")
}
var sys log.ISys
func TestMain(m *testing.M) {
var err error
if sys, err = log.NewSys(
log.SetFileName("log.log"),
log.SetIsDebug(false),
log.SetEncoder(log.TextEncoder),
); err != nil {
fmt.Println(err)
return
}
defer os.Exit(m.Run())
}
func Test_sys(t *testing.T) {
data := &TestData{}
data.Log()
}