[mirror] a bluesky bot to post golang projects
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

Update(cache): simple s3 based cache for larry

+145 -10
+29 -2
cmd/bot/main.go
··· 8 8 9 9 "log/slog" 10 10 11 + "github.com/minio/minio-go/v7" 12 + "github.com/minio/minio-go/v7/pkg/credentials" 11 13 bk "github.com/tailscale/go-bluesky" 12 14 "github.com/till/golangoss-bluesky/internal/bluesky" 13 15 "github.com/till/golangoss-bluesky/internal/content" ··· 16 18 var ( 17 19 blueskyHandle string = "till+bluesky-golang@lagged.biz" 18 20 blueskyAppKey string = "" 21 + 22 + cacheBucket string = "golangoss-cache-bucket" 19 23 20 24 ctx context.Context 21 25 ) ··· 53 57 } 54 58 } 55 59 60 + // init s3 client 61 + mc, err := minio.New(os.Getenv("AWS_ENDPOINT"), &minio.Options{ 62 + Creds: credentials.NewStaticV4(os.Getenv("AWS_ACCESS_KEY_ID"), os.Getenv("AWS_SECRET_KEY"), ""), 63 + Secure: true, 64 + }) 65 + if err != nil { 66 + slog.ErrorContext(ctx, "Failed to initialize MinIO client", slog.Any("err", err)) 67 + os.Exit(1) 68 + } 69 + 70 + // ensure the bucket exists 71 + if err := mc.MakeBucket(ctx, cacheBucket, minio.MakeBucketOptions{}); err != nil { 72 + slog.ErrorContext(ctx, "failed to create bucket", slog.Any("err", err)) 73 + os.Exit(1) 74 + } 75 + 56 76 c := bluesky.Client{ 57 77 Client: client, 58 78 } 59 79 60 - if err := content.Start(); err != nil { 61 - panic(err) 80 + cacheClient := &content.CacheClientS3{ 81 + MC: mc, 82 + Bucket: cacheBucket, 83 + CTX: ctx, 84 + } 85 + 86 + if err := content.Start(cacheClient); err != nil { 87 + slog.ErrorContext(ctx, "failed to start service", slog.Any("err", err)) 88 + os.Exit(1) 62 89 } 63 90 64 91 for {
+13 -5
go.mod
··· 11 11 github.com/carlmjohnson/versioninfo v0.22.5 // indirect 12 12 github.com/cespare/xxhash/v2 v2.2.0 // indirect 13 13 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect 14 + github.com/dustin/go-humanize v1.0.1 // indirect 14 15 github.com/felixge/httpsnoop v1.0.4 // indirect 16 + github.com/go-ini/ini v1.67.0 // indirect 15 17 github.com/go-logr/logr v1.4.1 // indirect 16 18 github.com/go-logr/stdr v1.2.2 // indirect 19 + github.com/goccy/go-json v0.10.3 // indirect 17 20 github.com/golang/protobuf v1.5.3 // indirect 18 21 github.com/google/go-github/v39 v39.2.0 // indirect 19 22 github.com/google/go-querystring v1.1.0 // indirect 23 + github.com/klauspost/compress v1.17.11 // indirect 24 + github.com/minio/md5-simd v1.1.2 // indirect 25 + github.com/rs/xid v1.6.0 // indirect 20 26 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect 21 27 go.opentelemetry.io/otel v1.21.0 // indirect 22 28 go.opentelemetry.io/otel/metric v1.21.0 // indirect 23 29 go.opentelemetry.io/otel/trace v1.21.0 // indirect 24 - golang.org/x/net v0.23.0 // indirect 30 + golang.org/x/net v0.30.0 // indirect 25 31 golang.org/x/oauth2 v0.8.0 // indirect 32 + golang.org/x/text v0.19.0 // indirect 26 33 google.golang.org/appengine v1.6.7 // indirect 27 34 google.golang.org/protobuf v1.33.0 // indirect 28 35 ) ··· 35 42 github.com/ezeoleaf/larry v0.10.0 36 43 github.com/gogo/protobuf v1.3.2 // indirect 37 44 github.com/golang-jwt/jwt/v5 v5.0.0 // indirect 38 - github.com/google/uuid v1.4.0 // indirect 45 + github.com/google/uuid v1.6.0 // indirect 39 46 github.com/hashicorp/go-cleanhttp v0.5.2 // indirect 40 47 github.com/hashicorp/go-retryablehttp v0.7.5 // indirect 41 48 github.com/hashicorp/golang-lru v1.0.2 // indirect ··· 52 59 github.com/ipfs/go-log/v2 v2.5.1 // indirect 53 60 github.com/ipfs/go-metrics-interface v0.0.1 // indirect 54 61 github.com/jbenet/goprocess v0.1.4 // indirect 55 - github.com/klauspost/cpuid/v2 v2.2.7 // indirect 62 + github.com/klauspost/cpuid/v2 v2.2.8 // indirect 56 63 github.com/mattn/go-isatty v0.0.20 // indirect 64 + github.com/minio/minio-go/v7 v7.0.80 57 65 github.com/minio/sha256-simd v1.0.1 // indirect 58 66 github.com/mr-tron/base58 v1.2.0 // indirect 59 67 github.com/multiformats/go-base32 v0.1.0 // indirect ··· 69 77 go.uber.org/atomic v1.11.0 // indirect 70 78 go.uber.org/multierr v1.11.0 // indirect 71 79 go.uber.org/zap v1.26.0 // indirect 72 - golang.org/x/crypto v0.21.0 // indirect 73 - golang.org/x/sys v0.22.0 // indirect 80 + golang.org/x/crypto v0.28.0 // indirect 81 + golang.org/x/sys v0.26.0 // indirect 74 82 golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect 75 83 lukechampine.com/blake3 v1.2.1 // indirect 76 84 )
+27
go.sum
··· 29 29 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= 30 30 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= 31 31 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= 32 + github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= 33 + github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= 32 34 github.com/ethereum/go-ethereum v1.9.3 h1:v3bE4abkXknLcyWCf4TRFn+Ecmm9thPtfLFvTEQ+1+U= 33 35 github.com/ethereum/go-ethereum v1.9.3/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY= 34 36 github.com/ezeoleaf/larry v0.10.0 h1:KjCfxPbTteLGdpE7XcnV2HhjZnL2j+AjA3jfhcuogXQ= ··· 38 40 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 39 41 github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= 40 42 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 43 + github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= 44 + github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= 41 45 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= 42 46 github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= 43 47 github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= ··· 46 50 github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= 47 51 github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= 48 52 github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= 53 + github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= 54 + github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= 49 55 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= 50 56 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 51 57 github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= ··· 68 74 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 69 75 github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= 70 76 github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 77 + github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 78 + github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 71 79 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= 72 80 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 73 81 github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= ··· 116 124 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= 117 125 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 118 126 github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= 127 + github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= 128 + github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= 129 + github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= 119 130 github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= 120 131 github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= 132 + github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= 133 + github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= 121 134 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 122 135 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 123 136 github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= ··· 128 141 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 129 142 github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 130 143 github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 144 + github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= 145 + github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= 146 + github.com/minio/minio-go/v7 v7.0.80 h1:2mdUHXEykRdY/BigLt3Iuu1otL0JTogT0Nmltg0wujk= 147 + github.com/minio/minio-go/v7 v7.0.80/go.mod h1:84gmIilaX4zcvAWWzJ5Z1WI5axN+hAbM5w25xf8xvC0= 131 148 github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= 132 149 github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= 133 150 github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= ··· 161 178 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 162 179 github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= 163 180 github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= 181 + github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= 182 + github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= 164 183 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 165 184 github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= 166 185 github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= ··· 223 242 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 224 243 golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= 225 244 golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= 245 + golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= 246 + golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= 226 247 golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 227 248 golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 228 249 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= ··· 239 260 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= 240 261 golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= 241 262 golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= 263 + golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= 264 + golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= 242 265 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 243 266 golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= 244 267 golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= ··· 260 283 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 261 284 golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= 262 285 golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 286 + golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= 287 + golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 263 288 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 264 289 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 265 290 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 266 291 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 267 292 golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= 268 293 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 294 + golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= 295 + golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 269 296 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 270 297 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 271 298 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+2 -3
internal/content/content.go
··· 7 7 "os" 8 8 "strings" 9 9 10 + "github.com/ezeoleaf/larry/cache" 10 11 "github.com/ezeoleaf/larry/config" 11 12 "github.com/ezeoleaf/larry/provider/github" 12 13 "github.com/till/golangoss-bluesky/internal/bluesky" ··· 16 17 provider github.Provider 17 18 ) 18 19 19 - func Start() error { 20 + func Start(cacheClient cache.Client) error { 20 21 if _, status := os.LookupEnv("GITHUB_TOKEN"); !status { 21 22 panic("No github token") 22 23 } ··· 24 25 cfg := config.Config{ 25 26 Language: "go", 26 27 } 27 - 28 - cacheClient := &CacheClientProcess{} 29 28 30 29 provider = github.NewProvider(os.Getenv("GITHUB_TOKEN"), cfg, cacheClient) 31 30 return nil
+74
internal/content/s3_cache.go
··· 1 + package content 2 + 3 + import ( 4 + "bytes" 5 + "context" 6 + "encoding/json" 7 + "strconv" 8 + "time" 9 + 10 + "github.com/go-redis/redis/v8" 11 + "github.com/minio/minio-go/v7" 12 + ) 13 + 14 + // CacheClientS3 is a small cache that is backed by an S3-compatible store 15 + type CacheClientS3 struct { 16 + MC *minio.Client 17 + Bucket string 18 + CTX context.Context 19 + } 20 + 21 + func (c *CacheClientS3) Set(key string, value interface{}, exp time.Duration) error { 22 + data, err := json.Marshal(value) 23 + if err != nil { 24 + return err 25 + } 26 + 27 + r := bytes.NewReader(data) 28 + 29 + _, err = c.MC.PutObject(c.CTX, c.Bucket, key, r, int64(r.Len()), minio.PutObjectOptions{ 30 + Expires: time.Now().Add(exp), 31 + }) 32 + return err 33 + } 34 + 35 + // Get returns an object, it follows the original pattern in larry to return redis.Nil when an object 36 + // does not exist, in other case we can use minio.ToErrorResponse(err) to extract more details about the 37 + // potential S3 related error 38 + func (c *CacheClientS3) Get(key string) (string, error) { 39 + if _, err := c.MC.StatObject(c.CTX, c.Bucket, key, minio.StatObjectOptions{}); err != nil { 40 + return "", redis.Nil 41 + } 42 + 43 + object, err := c.MC.GetObject(c.CTX, c.Bucket, key, minio.GetObjectOptions{}) 44 + if err != nil { 45 + return "", err 46 + } 47 + 48 + var val any 49 + 50 + if err := json.NewDecoder(object).Decode(&val); err != nil { 51 + return "", err 52 + } 53 + 54 + // not even sure why this method returns a string, when it's only used for bools 55 + switch v := val.(type) { 56 + case bool: 57 + return strconv.FormatBool(v), nil 58 + case string: 59 + return v, nil 60 + default: 61 + panic("unknown type") 62 + } 63 + } 64 + 65 + func (c *CacheClientS3) Del(key string) error { 66 + return c.MC.RemoveObject(c.CTX, c.Bucket, key, minio.RemoveObjectOptions{ 67 + ForceDelete: true, 68 + }) 69 + } 70 + 71 + func (c *CacheClientS3) Scan(key string, action func(context.Context, string) error) error { 72 + 73 + return nil 74 + }