diff --git a/main.go b/main.go index d2f33a6..5739218 100644 --- a/main.go +++ b/main.go @@ -9,6 +9,7 @@ import ( "net/http" "raycat/internal/pkg/tinypool" "strconv" + "strings" "github.com/ServiceWeaver/weaver" ) @@ -36,14 +37,22 @@ type app struct { // serve serves HTTP traffic. func serve(ctx context.Context, app *app) error { - http.HandleFunc("/x", subShareHandlerApp(app)) + config := app.configure.Get() + subPublishPath, err := config.GetSubPublishPath(ctx) + if err != nil { + app.Logger(ctx).Warn("failed to get sub publish path,will use /subscribe as default", "err", err) + subPublishPath = "/subscribe" + } + if !strings.HasPrefix(subPublishPath, "/") { + subPublishPath = "/" + subPublishPath + } + http.HandleFunc(subPublishPath, subShareHandlerApp(app)) app.Logger(ctx).Info("Listening on...", "address", app.lis) return http.Serve(app.lis, nil) } func subShareHandlerApp(app *app) func(w http.ResponseWriter, _ *http.Request) { return func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization,profile-web-page-url,profile-update-interval") diff --git a/sub_configure.go b/sub_configure.go index 818aa96..6310219 100644 --- a/sub_configure.go +++ b/sub_configure.go @@ -7,7 +7,8 @@ import ( ) var ( - noResponseOptionConfiguredError = errors.New("no response option configured") + responseOptionNotConfiguredError = errors.New("no response option configured") + subPublishPathNotConfiguredError = errors.New("sub publish path not configured") ) var _ subConfigureProvider = (*subConfigure)(nil) @@ -15,6 +16,7 @@ var _ subConfigureProvider = (*subConfigure)(nil) type subConfigureProvider interface { GetSubFilePaths(ctx context.Context, privateSubToken string) ([]string, error) GetUrlSubs(ctx context.Context, privateSubToken string) ([]string, int, error) + GetSubPublishPath(ctx context.Context) (string, error) GetResponseOption(ctx context.Context) (*responseOption, error) } @@ -27,6 +29,7 @@ type subConfig struct { PrivateUrlSubs []string `toml:"private_url_subs"` PrivateSubToken string `toml:"private_sub_token"` + SubPublishPath string `toml:"sub_publish_path,omitempty"` ResponseOption *responseOption `toml:"response_option,omitempty"` } @@ -60,10 +63,17 @@ func (s *subConfigure) GetUrlSubs(ctx context.Context, privateSubToken string) ( return append(config.PrivateUrlSubs, config.PublicUrlSubs...), config.UrlSubFetchTimeoutSeconds, nil } +func (s *subConfigure) GetSubPublishPath(ctx context.Context) (string, error) { + if s.Config().SubPublishPath == "" { + return "", subPublishPathNotConfiguredError + } + return s.Config().SubPublishPath, nil +} + func (s *subConfigure) GetResponseOption(ctx context.Context) (*responseOption, error) { config := s.Config() if config.ResponseOption == nil { - return nil, noResponseOptionConfiguredError + return nil, responseOptionNotConfiguredError } return config.ResponseOption, nil } diff --git a/weaver.toml b/weaver.toml index 619ed8a..a2a1299 100644 --- a/weaver.toml +++ b/weaver.toml @@ -33,6 +33,7 @@ private_url_subs = [ "url4" ] private_sub_token = "gopher" +sub_publish_path = "/subscibe" ["raycat/subConfigureProvider".response_option] update_interval_hours = 8 profile_web_page = "https://x.com" diff --git a/weaver_gen.go b/weaver_gen.go index 6936045..62bb37b 100644 --- a/weaver_gen.go +++ b/weaver_gen.go @@ -37,10 +37,10 @@ func init() { Iface: reflect.TypeOf((*subConfigureProvider)(nil)).Elem(), Impl: reflect.TypeOf(subConfigure{}), LocalStubFn: func(impl any, caller string, tracer trace.Tracer) any { - return subConfigureProvider_local_stub{impl: impl.(subConfigureProvider), tracer: tracer, getResponseOptionMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "raycat/subConfigureProvider", Method: "GetResponseOption", Remote: false, Generated: true}), getSubFilePathsMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "raycat/subConfigureProvider", Method: "GetSubFilePaths", Remote: false, Generated: true}), getUrlSubsMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "raycat/subConfigureProvider", Method: "GetUrlSubs", Remote: false, Generated: true})} + return subConfigureProvider_local_stub{impl: impl.(subConfigureProvider), tracer: tracer, getResponseOptionMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "raycat/subConfigureProvider", Method: "GetResponseOption", Remote: false, Generated: true}), getSubFilePathsMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "raycat/subConfigureProvider", Method: "GetSubFilePaths", Remote: false, Generated: true}), getSubPublishPathMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "raycat/subConfigureProvider", Method: "GetSubPublishPath", Remote: false, Generated: true}), getUrlSubsMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "raycat/subConfigureProvider", Method: "GetUrlSubs", Remote: false, Generated: true})} }, ClientStubFn: func(stub codegen.Stub, caller string) any { - return subConfigureProvider_client_stub{stub: stub, getResponseOptionMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "raycat/subConfigureProvider", Method: "GetResponseOption", Remote: true, Generated: true}), getSubFilePathsMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "raycat/subConfigureProvider", Method: "GetSubFilePaths", Remote: true, Generated: true}), getUrlSubsMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "raycat/subConfigureProvider", Method: "GetUrlSubs", Remote: true, Generated: true})} + return subConfigureProvider_client_stub{stub: stub, getResponseOptionMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "raycat/subConfigureProvider", Method: "GetResponseOption", Remote: true, Generated: true}), getSubFilePathsMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "raycat/subConfigureProvider", Method: "GetSubFilePaths", Remote: true, Generated: true}), getSubPublishPathMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "raycat/subConfigureProvider", Method: "GetSubPublishPath", Remote: true, Generated: true}), getUrlSubsMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "raycat/subConfigureProvider", Method: "GetUrlSubs", Remote: true, Generated: true})} }, ServerStubFn: func(impl any, addLoad func(uint64, float64)) codegen.Server { return subConfigureProvider_server_stub{impl: impl.(subConfigureProvider), addLoad: addLoad} @@ -115,6 +115,7 @@ type subConfigureProvider_local_stub struct { tracer trace.Tracer getResponseOptionMetrics *codegen.MethodMetrics getSubFilePathsMetrics *codegen.MethodMetrics + getSubPublishPathMetrics *codegen.MethodMetrics getUrlSubsMetrics *codegen.MethodMetrics } @@ -161,6 +162,26 @@ func (s subConfigureProvider_local_stub) GetSubFilePaths(ctx context.Context, a0 return s.impl.GetSubFilePaths(ctx, a0) } +func (s subConfigureProvider_local_stub) GetSubPublishPath(ctx context.Context) (r0 string, err error) { + // Update metrics. + begin := s.getSubPublishPathMetrics.Begin() + defer func() { s.getSubPublishPathMetrics.End(begin, err != nil, 0, 0) }() + span := trace.SpanFromContext(ctx) + if span.SpanContext().IsValid() { + // Create a child span for this method. + ctx, span = s.tracer.Start(ctx, "main.subConfigureProvider.GetSubPublishPath", trace.WithSpanKind(trace.SpanKindInternal)) + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, err.Error()) + } + span.End() + }() + } + + return s.impl.GetSubPublishPath(ctx) +} + func (s subConfigureProvider_local_stub) GetUrlSubs(ctx context.Context, a0 string) (r0 []string, r1 int, err error) { // Update metrics. begin := s.getUrlSubsMetrics.Begin() @@ -252,6 +273,7 @@ type subConfigureProvider_client_stub struct { stub codegen.Stub getResponseOptionMetrics *codegen.MethodMetrics getSubFilePathsMetrics *codegen.MethodMetrics + getSubPublishPathMetrics *codegen.MethodMetrics getUrlSubsMetrics *codegen.MethodMetrics } @@ -361,6 +383,53 @@ func (s subConfigureProvider_client_stub) GetSubFilePaths(ctx context.Context, a return } +func (s subConfigureProvider_client_stub) GetSubPublishPath(ctx context.Context) (r0 string, err error) { + // Update metrics. + var requestBytes, replyBytes int + begin := s.getSubPublishPathMetrics.Begin() + defer func() { s.getSubPublishPathMetrics.End(begin, err != nil, requestBytes, replyBytes) }() + + span := trace.SpanFromContext(ctx) + if span.SpanContext().IsValid() { + // Create a child span for this method. + ctx, span = s.stub.Tracer().Start(ctx, "main.subConfigureProvider.GetSubPublishPath", trace.WithSpanKind(trace.SpanKindClient)) + } + + defer func() { + // Catch and return any panics detected during encoding/decoding/rpc. + if err == nil { + err = codegen.CatchPanics(recover()) + if err != nil { + err = errors.Join(weaver.RemoteCallError, err) + } + } + + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, err.Error()) + } + span.End() + + }() + + var shardKey uint64 + + // Call the remote method. + var results []byte + results, err = s.stub.Run(ctx, 2, nil, shardKey) + replyBytes = len(results) + if err != nil { + err = errors.Join(weaver.RemoteCallError, err) + return + } + + // Decode the results. + dec := codegen.NewDecoder(results) + r0 = dec.String() + err = dec.Error() + return +} + func (s subConfigureProvider_client_stub) GetUrlSubs(ctx context.Context, a0 string) (r0 []string, r1 int, err error) { // Update metrics. var requestBytes, replyBytes int @@ -403,7 +472,7 @@ func (s subConfigureProvider_client_stub) GetUrlSubs(ctx context.Context, a0 str // Call the remote method. requestBytes = len(enc.Data()) var results []byte - results, err = s.stub.Run(ctx, 2, enc.Data(), shardKey) + results, err = s.stub.Run(ctx, 3, enc.Data(), shardKey) replyBytes = len(results) if err != nil { err = errors.Join(weaver.RemoteCallError, err) @@ -593,6 +662,8 @@ func (s subConfigureProvider_server_stub) GetStubFn(method string) func(ctx cont return s.getResponseOption case "GetSubFilePaths": return s.getSubFilePaths + case "GetSubPublishPath": + return s.getSubPublishPath case "GetUrlSubs": return s.getUrlSubs default: @@ -645,6 +716,26 @@ func (s subConfigureProvider_server_stub) getSubFilePaths(ctx context.Context, a return enc.Data(), nil } +func (s subConfigureProvider_server_stub) getSubPublishPath(ctx context.Context, args []byte) (res []byte, err error) { + // Catch and return any panics detected during encoding/decoding/rpc. + defer func() { + if err == nil { + err = codegen.CatchPanics(recover()) + } + }() + + // TODO(rgrandl): The deferred function above will recover from panics in the + // user code: fix this. + // Call the local method. + r0, appErr := s.impl.GetSubPublishPath(ctx) + + // Encode the results. + enc := codegen.NewEncoder() + enc.String(r0) + enc.Error(appErr) + return enc.Data(), nil +} + func (s subConfigureProvider_server_stub) getUrlSubs(ctx context.Context, args []byte) (res []byte, err error) { // Catch and return any panics detected during encoding/decoding/rpc. defer func() { @@ -785,6 +876,11 @@ func (s subConfigureProvider_reflect_stub) GetSubFilePaths(ctx context.Context, return } +func (s subConfigureProvider_reflect_stub) GetSubPublishPath(ctx context.Context) (r0 string, err error) { + err = s.caller("GetSubPublishPath", ctx, []any{}, []any{&r0}) + return +} + func (s subConfigureProvider_reflect_stub) GetUrlSubs(ctx context.Context, a0 string) (r0 []string, r1 int, err error) { err = s.caller("GetUrlSubs", ctx, []any{a0}, []any{&r0, &r1}) return @@ -852,6 +948,7 @@ type __is_subConfig[T ~struct { PublicUrlSubs []string "toml:\"public_url_subs\"" PrivateUrlSubs []string "toml:\"private_url_subs\"" PrivateSubToken string "toml:\"private_sub_token\"" + SubPublishPath string "toml:\"sub_publish_path,omitempty\"" ResponseOption *responseOption "toml:\"response_option,omitempty\"" }] struct{} @@ -867,6 +964,7 @@ func (x *subConfig) WeaverMarshal(enc *codegen.Encoder) { serviceweaver_enc_slice_string_4af10117(enc, x.PublicUrlSubs) serviceweaver_enc_slice_string_4af10117(enc, x.PrivateUrlSubs) enc.String(x.PrivateSubToken) + enc.String(x.SubPublishPath) serviceweaver_enc_ptr_responseOption_4a459b91(enc, x.ResponseOption) } @@ -880,6 +978,7 @@ func (x *subConfig) WeaverUnmarshal(dec *codegen.Decoder) { x.PublicUrlSubs = serviceweaver_dec_slice_string_4af10117(dec) x.PrivateUrlSubs = serviceweaver_dec_slice_string_4af10117(dec) x.PrivateSubToken = dec.String() + x.SubPublishPath = dec.String() x.ResponseOption = serviceweaver_dec_ptr_responseOption_4a459b91(dec) }