Commit ca78aa97 authored by Vladimir Barsukov's avatar Vladimir Barsukov
Browse files

zgo

parent cb27f278
package devops
import "github.com/gin-gonic/gin"
func AngryHandler(c *gin.Context) {
c.Data(200, "text/plain; charset=utf-8", []byte("Чё пасёшь?"))
}
module git.barsukov.pro/barsukov/zgo
go 1.20
go 1.21
require (
github.com/georgysavva/scany/v2 v2.0.0
github.com/gin-gonic/gin v1.9.1
github.com/go-co-op/gocron v1.30.1
github.com/go-co-op/gocron v1.36.0
github.com/goccy/go-json v0.10.2
github.com/google/uuid v1.3.0
github.com/jackc/pgx/v5 v5.4.2
github.com/google/uuid v1.4.0
github.com/jackc/pgx/v5 v5.5.0
github.com/patrickmn/go-cache v2.1.0+incompatible
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
)
require (
github.com/bytedance/sonic v1.9.1 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/bytedance/sonic v1.10.2 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/chenzhuoyu/iasm v0.9.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/go-playground/validator/v10 v10.16.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/puddle/v2 v2.2.0 // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
go.uber.org/atomic v1.9.0 // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/crypto v0.9.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
golang.org/x/arch v0.6.0 // indirect
golang.org/x/crypto v0.15.0 // indirect
golang.org/x/net v0.18.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
github.com/bytedance/sonic v1.10.2 h1:GQebETVBxYB7JGWJtLBi07OVzWwt+8dWA00gEVW2ZFE=
github.com/bytedance/sonic v1.10.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0=
github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
github.com/cockroachdb/cockroach-go/v2 v2.2.0 h1:/5znzg5n373N/3ESjHF5SMLxiW4RKB05Ql//KWfeTFs=
github.com/cockroachdb/cockroach-go/v2 v2.2.0/go.mod h1:u3MiKYGupPPjkn3ozknpMUpxPaNLTFWAya419/zv6eI=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/georgysavva/scany/v2 v2.0.0 h1:RGXqxDv4row7/FYoK8MRXAZXqoWF/NM+NP0q50k3DKU=
github.com/georgysavva/scany/v2 v2.0.0/go.mod h1:sigOdh+0qb/+aOs3TVhehVT10p8qJL7K/Zhyz8vWo38=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/go-co-op/gocron v1.30.1 h1:tjWUvJl5KrcwpkEkSXFSQFr4F9h5SfV/m4+RX0cV2fs=
github.com/go-co-op/gocron v1.30.1/go.mod h1:39f6KNSGVOU1LO/ZOoZfcSxwlsJDQOKSu8erN0SH48Y=
github.com/go-co-op/gocron v1.36.0 h1:sEmAwg57l4JWQgzaVWYfKZ+w13uHOqeOtwjo72Ll5Wc=
github.com/go-co-op/gocron v1.36.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-playground/validator/v10 v10.16.0 h1:x+plE831WK4vaKHO/jpgUGsvLKIqRRkz6M78GuJAfGE=
github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.4.2 h1:u1gmGDwbdRUZiwisBm/Ky2M14uQyUP65bG8+20nnyrg=
github.com/jackc/pgx/v5 v5.4.2/go.mod h1:q6iHT8uDNXWiFNOlRqJzBTaSH3+2xCXkokxHZC5qWFY=
github.com/jackc/puddle/v2 v2.2.0 h1:RdcDk92EJBuBS55nQMMYFXTxwstHug4jkhT5pq8VxPk=
github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jackc/pgx/v5 v5.5.0 h1:NxstgwndsTRy7eq9/kqYc/BZh5w2hHJV86wjvO+1xPw=
github.com/jackc/pgx/v5 v5.5.0/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
......@@ -59,8 +69,9 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/lib/pq v1.10.0 h1:Zx5DJFEYQXio93kgXnQ09fXNiUKsqv4OUEu2UtGcB1E=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
......@@ -68,10 +79,11 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
......@@ -79,6 +91,7 @@ github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzG
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
......@@ -89,35 +102,36 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/arch v0.6.0 h1:S0JTfE48HbRj80+4tbvZDYsJ3tGv6BUU3XxyZ7CirAc=
golang.org/x/arch v0.6.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
......@@ -126,4 +140,5 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
package komrad
package zatomic
import "sync/atomic"
type Int struct {
v *atomic.Int32
}
func New() *Int {
return &Int{v: &atomic.Int32{}}
}
func (i *Int) Store(v int) {
i.v.Store(int32(v))
}
func (i *Int) Add(delta int) int {
return int(i.v.Add(int32(delta)))
}
func (i *Int) Load() int {
return int(i.v.Load())
}
func (i *Int) LoadInverse() int {
return i.Load() * -1
}
......@@ -55,7 +55,7 @@ func (d *Pool) qAny(q *Conn, dst any, sql string, args ...any) error {
} else if f.DataTypeOID == pgtype.NumericOID {
ff, _ := v[i].(pgtype.Numeric).Float64Value()
r[f.Name] = ff.Float64
} else if f.DataTypeOID == pgtype.TimestampOID {
} else if f.DataTypeOID == pgtype.TimestampOID && d.UseGoTime == false {
r[f.Name] = v[i].(time.Time).Format(d.PgTsFormat)
} else if f.DataTypeOID == pgtype.UUIDOID {
bb := v[i].([16]byte)
......
......@@ -8,8 +8,10 @@ import (
type Conn struct {
*pgxpool.Pool
Mode connMode
Alive bool
Index int
Mode connMode
Alive bool
PingTry int
}
type connMode int
......
//go:build dev
package zdb
import "log"
func logConnStat(conn *Conn) {
log.Printf("\033[9%dm%s\u001B[0m -> idle: %d; acquired: %d, total: %d, max: %d, ratio: %0.2f",
conn.Index+1,
conn.ToString(),
conn.Stat().IdleConns(),
conn.Stat().AcquiredConns(),
conn.Stat().TotalConns(),
conn.Stat().MaxConns(),
float64(conn.Stat().AcquiredConns())/float64(conn.Stat().MaxConns()),
)
}
......@@ -3,6 +3,7 @@ package zdb
import (
"errors"
"github.com/jackc/pgx/v5"
"strings"
)
var ErrNoRows = pgx.ErrNoRows
......@@ -15,6 +16,20 @@ type Opts interface {
Opts() (sql string, args map[string]any)
}
func remove[T comparable](slice []T, s int) []T {
return append(slice[:s], slice[s+1:]...)
}
func contains(s string, sl []string) bool {
for _, s2 := range sl {
if strings.Contains(s, s2) {
return true
}
}
return false
}
type Logger interface {
Printf(format string, v ...any)
}
......@@ -4,7 +4,6 @@ import (
"context"
"errors"
"fmt"
"git.barsukov.pro/barsukov/zgo/zutils"
"github.com/jackc/pgx/v5/pgxpool"
"log"
"reflect"
......@@ -33,11 +32,14 @@ type Pool struct {
slavesAsyncIter *atomic.Int64
stop bool
PgTsFormat string
UseGoTime bool
Continues []string
ContinuesTry []string
TryOnError int
TryOnSleep time.Duration
Balance Balance
PingTimout time.Duration
PingTry int
}
func New(ctx context.Context) *Pool {
......@@ -47,11 +49,13 @@ func New(ctx context.Context) *Pool {
slavesIter: &atomic.Int64{},
slavesAsyncIter: &atomic.Int64{},
PgTsFormat: "2006-01-02 15:04:05",
Continues: []string{"connect", "EOF", "conflict with recovery"},
Continues: []string{"connect", "EOF", "conflict with recovery", "context deadline exceeded"},
ContinuesTry: []string{"conflict with recovery"},
TryOnError: 1,
TryOnSleep: time.Second,
Balance: BalanceLeastConn,
PingTimout: time.Second * 5,
PingTry: 5,
}
}
......@@ -74,12 +78,15 @@ func (d *Pool) WithContext(ctx context.Context) *Pool {
slavesIter: d.slavesIter,
slavesAsyncIter: d.slavesAsyncIter,
stop: d.stop,
UseGoTime: d.UseGoTime,
PgTsFormat: d.PgTsFormat,
Continues: d.Continues,
ContinuesTry: d.ContinuesTry,
TryOnError: d.TryOnError,
TryOnSleep: d.TryOnSleep,
Balance: d.Balance,
PingTimout: d.PingTimout,
PingTry: d.PingTry,
}
}
......@@ -105,8 +112,10 @@ func (d *Pool) NewConn(mode connMode, pgConnString string) error {
case ConnModeMaster:
d.SrvMaster = q
case ConnModeSync:
q.Index = len(d.SrvSync)
d.SrvSync = append(d.SrvSync, q)
case ConnModeAsync:
q.Index = len(d.SrvAsync)
d.SrvAsync = append(d.SrvAsync, q)
default:
return errors.New("unknown mode")
......@@ -151,7 +160,7 @@ func (d *Pool) newConn(mode connMode, pgConnString string) (q *Conn, err error)
q = &Conn{Pool: pgxPool, Alive: false, Mode: mode}
if err = d.ping(q); err != nil {
if err = d.Ping(q); err != nil {
return q, err
}
......@@ -160,6 +169,24 @@ func (d *Pool) newConn(mode connMode, pgConnString string) (q *Conn, err error)
return q, nil
}
func (d *Pool) least(s []*Conn) *Conn {
var out *Conn
var m float64 = 0
for i, conn := range s {
ratio := float64(conn.Stat().AcquiredConns()) / float64(conn.Stat().MaxConns())
if ratio < m || i == 0 {
m = ratio
out = conn
}
}
logConnStat(out)
return out
}
func (d *Pool) sync() *Conn {
if len(d.SrvSync) == 0 {
return d.SrvMaster
......@@ -176,17 +203,7 @@ func (d *Pool) sync() *Conn {
return d.SrvSync[d.slavesIter.Add(1)%int64(len(d.SrvSync))]
}
var out *Conn
var min int32 = 1 << 30
for _, conn := range d.SrvSync {
if conn.Stat().AcquiredConns() < min {
min = conn.Stat().AcquiredConns()
out = conn
}
}
return out
return d.least(d.SrvSync)
}
func (d *Pool) async() *Conn {
......@@ -205,17 +222,7 @@ func (d *Pool) async() *Conn {
return d.SrvAsync[d.slavesAsyncIter.Add(1)%int64(len(d.SrvAsync))]
}
var out *Conn
var min int32 = 1 << 30
for _, conn := range d.SrvAsync {
if conn.Stat().AcquiredConns() < min {
min = conn.Stat().AcquiredConns()
out = conn
}
}
return out
return d.least(d.SrvAsync)
}
func (d *Pool) execWrapper(pool connMode, dst any, f func(conn *Conn, dst1 any) error) error {
......@@ -235,17 +242,17 @@ func (d *Pool) execWrapper(pool connMode, dst any, f func(conn *Conn, dst1 any)
return err
} else {
if try < d.TryOnError && zutils.Contains(err.Error(), d.ContinuesTry) {
if try < d.TryOnError && contains(err.Error(), d.ContinuesTry) {
try++
d.logger.Printf("DB_EXEC_WRAPPER_REPEAT_ERR: SRV: %s TRY: %d; %s", q.ToString(), try, err.Error())
d.logger.Printf("ZDB_EXEC_WRAPPER_REPEAT_ERR: SRV: %s TRY: %d; %s", q.ToString(), try, err.Error())
time.Sleep(d.TryOnSleep)
goto repeat
}
if zutils.Contains(err.Error(), d.Continues) {
if contains(err.Error(), d.Continues) {
d.setNotAliveConn(q)
d.logger.Printf("DB_EXEC_WRAPPER_ERR: SRV: %s; %s", q.ToString(), err.Error())
d.logger.Printf("ZDB_EXEC_WRAPPER_ERR: SRV: %s; %s", q.ToString(), err.Error())
continue
} else {
return err
......@@ -257,16 +264,25 @@ func (d *Pool) execWrapper(pool connMode, dst any, f func(conn *Conn, dst1 any)
}
}
func (d *Pool) ping(q *Conn) (err error) {
func (d *Pool) Ping(q *Conn) (err error) {
var n any
if err = d.qGet(q, &n, "SELECT 1"); err != nil {
d.logger.Printf("DB_PING_ERR: SRV: %s; %v",
if err = d.WithTimeout(d.PingTimout).qGet(q, &n, "SELECT 1"); err != nil {
q.PingTry++
d.logger.Printf("ZDB_PING_ERR: SRV: %s; TRY: %d; %v",
q.ToString(),
q.PingTry,
err,
)
if d.PingTry <= q.PingTry {
return nil
}
}
q.PingTry = 0
return
}
......@@ -278,7 +294,7 @@ func (d *Pool) setNotAliveConn(conn *Conn) {
if slave == conn {
conn.Alive = false
d.notAliveConns = append(d.notAliveConns, conn)
d.SrvSync = zutils.ArrayRemove(d.SrvSync, i)
d.SrvSync = remove(d.SrvSync, i)
return
}
}
......@@ -287,7 +303,7 @@ func (d *Pool) setNotAliveConn(conn *Conn) {
if slave == conn {
conn.Alive = false
d.notAliveConns = append(d.notAliveConns, conn)
d.SrvAsync = zutils.ArrayRemove(d.SrvAsync, i)
d.SrvAsync = remove(d.SrvAsync, i)
return
}
......@@ -303,22 +319,24 @@ func (d *Pool) Start() {
return
}
rep:
for i, q := range d.notAliveConns {
if err := d.ping(q); err == nil {
if err := d.Ping(q); err == nil {
d.mu.Lock()
q.Alive = true
d.notAliveConns = zutils.ArrayRemove(d.notAliveConns, i)
d.notAliveConns = remove(d.notAliveConns, i)
if q.Mode == ConnModeSync {
d.SrvSync = append(d.SrvSync, q)
} else if q.Mode == ConnModeAsync {
d.SrvAsync = append(d.SrvAsync, q)
}
d.mu.Unlock()
goto rep
}
}
if d.SrvMaster != nil {
d.SrvMaster.Alive = d.ping(d.SrvMaster) == nil
d.SrvMaster.Alive = d.Ping(d.SrvMaster) == nil
}
time.Sleep(time.Second)
......@@ -405,8 +423,21 @@ func (d *Pool) prepare(sql string, param map[string]any) string {
}
}
if _, ok := param["_debug"]; ok {
d.logger.Printf(sql)
if v, ok := param["_debug"]; ok {
switch vv := v.(type) {
case bool:
if vv {
d.logger.Printf(sql)
}
case int, uint:
if vv == 1 {
d.logger.Printf(sql)
}
case string:
if vv == "1" {
d.logger.Printf(sql)
}
}
}
return sql
......
//go:build !dev
package zdb
func logConnStat(conn *Conn) {
}
package zdwh
import "github.com/gin-gonic/gin"
func TableHandler(c *gin.Context) {
}
package zgo
import (
_ "git.barsukov.pro/barsukov/zgo/zatomic"
_ "git.barsukov.pro/barsukov/zgo/zcache"
_ "git.barsukov.pro/barsukov/zgo/zcron"
_ "git.barsukov.pro/barsukov/zgo/zdb"
_ "git.barsukov.pro/barsukov/zgo/zgin"
_ "git.barsukov.pro/barsukov/zgo/zjson"
_ "git.barsukov.pro/barsukov/zgo/zq"
_ "git.barsukov.pro/barsukov/zgo/zquit"
_ "git.barsukov.pro/barsukov/zgo/zutils"
_ "git.barsukov.pro/barsukov/zgo/zwg"
)
func ZGO() {
println("zgo")
}
package zq
import (
"git.barsukov.pro/barsukov/zgo/zatomic"
"git.barsukov.pro/barsukov/zgo/zwg"
)
type ZQ struct {
WorkerCounter *zatomic.Int
WorkerFn func(any)
JobsWg *zwg.Zwg
complete chan bool
jobs chan any
}
func New(qtyWorkers int, w func(any)) *ZQ {
q := &ZQ{
WorkerCounter: zatomic.New(),
WorkerFn: w,
JobsWg: zwg.New(),
jobs: make(chan any),
complete: make(chan bool),
}
for i := 0; i < qtyWorkers; i++ {
q.AddWorker(1)
}
return q
}
func (q *ZQ) AddWorker(delta int) {
if delta < 1 {
for i := 0; i < delta*-1; i++ {
q.complete <- true
}
return
}
for i := 0; i < delta; i++ {
q.WorkerCounter.Add(1)
go func() {
defer q.WorkerCounter.Add(-1)
for {
select {
case <-q.complete:
return
case j := <-q.jobs:
q.WorkerFn(j)
q.JobsWg.Done()
}
}
}()
}
}
func (q *ZQ) RemoveWorker() {
q.AddWorker(-1)
}
func (q *ZQ) AddJob(a any) {
q.JobsWg.Inc()
go func() {
q.jobs <- a
}()
}
func (q *ZQ) Wait() {
q.JobsWg.Wait()
}
func (q *ZQ) Quit() {
q.Wait()
q.AddWorker(q.WorkerCounter.LoadInverse())
}
package zqueue
import (
"errors"
"fmt"
"git.barsukov.pro/barsukov/zgo/zgin"
"github.com/gin-gonic/gin"
"sync"
)
type ZQueue struct {
queue map[string]chan *ZJob
mu sync.Mutex
}
type ZJob struct {
Id int64 `json:"id"`
Body any `json:"body"`
Result chan any `json:"-"`
Wg *sync.WaitGroup `json:"-"`
}
func New() *ZQueue {
return &ZQueue{}
}
func Default() *ZQueue {
return &ZQueue{}
}
func (q *ZQueue) GetHandler(c *gin.Context) {
queue := c.Param("queue")
if qChan, ok := q.queue[queue]; !ok {
zgin.Err(c, errors.New(fmt.Sprintf("unknown queue: '%s'", queue)))
} else {
job := <-qChan
zgin.Ok(c, job.Body)
return
}
}
func (q *ZQueue) PostHandler(c *gin.Context) {
}
func (q *ZQueue) NewHandler(c *gin.Context) {
}
package zquit
import (
"git.barsukov.pro/barsukov/zgo/zwg"
"github.com/gin-gonic/gin"
"net/http"
"os"
"os/signal"
"sync"
"sync/atomic"
"syscall"
)
type ZQuit struct {
isQuit bool
delta atomic.Int32
wg sync.WaitGroup
wg *zwg.Zwg
}
func Default() *ZQuit {
return &ZQuit{}
}
func (q *ZQuit) Add(delta int) {
q.delta.Add(int32(delta))
q.wg.Add(delta)
func New() *ZQuit {
return &ZQuit{
wg: zwg.New(),
}
}
func (q *ZQuit) Inc() {
q.Add(1)
q.wg.Inc()
}
func (q *ZQuit) Done() {
q.delta.Add(-1)
q.wg.Done()
}
......@@ -39,19 +33,15 @@ func (q *ZQuit) Wait() {
}
func (q *ZQuit) IncDefer() func() {
q.Inc()
return func() {
q.Done()
}
return q.wg.IncDefer()
}
func (q *ZQuit) IsQuit() bool {
return q.isQuit
}
func (q *ZQuit) Delta() int32 {
return q.delta.Load()
func (q *ZQuit) Val() int {
return q.wg.Val()
}
func (q *ZQuit) WaitInterruptPrePost(pre func(), post func()) {
......
package ztg
import (
"net/http"
"time"
)
type ZTg struct {
client *http.Client
botKey string
defaultProps map[string]any
mode int
batch bool
apiUrl string
}
func Default(botKey string) *ZTg {
return &ZTg{
client: &http.Client{Timeout: time.Second * 5},
botKey: botKey,
defaultProps: map[string]any{
"parse_mode": "HTML",
},
mode: 0,
batch: false,
apiUrl: "",
}
}
package zwg
import (
"sync"
"sync/atomic"
)
type Zwg struct {
store *atomic.Int32
wg *sync.WaitGroup
}
func (w *Zwg) Add(delta int) {
w.store.Add(int32(delta))
w.wg.Add(delta)
}
func (w *Zwg) Inc() *Zwg {
w.store.Add(1)
w.wg.Add(1)
return w
}
func (w *Zwg) IncDefer() func() {
w.Inc()
return func() {
w.Done()
}
}
func (w *Zwg) Done() {
w.store.Add(-1)
w.wg.Done()
}
func (w *Zwg) Wait() {
w.wg.Wait()
}
func (w *Zwg) Val() int {
return int(w.store.Load())
}
func (w *Zwg) IsEmpty() bool {
return w.Val() == 0
}
func New() *Zwg {
zwg := &Zwg{
store: &atomic.Int32{},
wg: &sync.WaitGroup{},
}
return zwg
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment