github.com/anycable/anycable-go@v1.5.1/cli/runner_options.go (about)

     1  package cli
     2  
     3  import (
     4  	"log/slog"
     5  	"os"
     6  	"strings"
     7  
     8  	"github.com/anycable/anycable-go/broadcast"
     9  	"github.com/anycable/anycable-go/broker"
    10  	"github.com/anycable/anycable-go/config"
    11  	"github.com/anycable/anycable-go/metrics"
    12  	"github.com/anycable/anycable-go/node"
    13  	"github.com/anycable/anycable-go/pubsub"
    14  	"github.com/anycable/anycable-go/rpc"
    15  	"github.com/joomcode/errorx"
    16  )
    17  
    18  // Option represents a Runner configuration function
    19  type Option func(*Runner) error
    20  
    21  // WithName is an Option to set Runner name
    22  func WithName(name string) Option {
    23  	return func(r *Runner) error {
    24  		r.name = name
    25  		return nil
    26  	}
    27  }
    28  
    29  // WithController is an Option to set Runner controller
    30  func WithController(fn controllerFactory) Option {
    31  	return func(r *Runner) error {
    32  		if r.controllerFactory != nil {
    33  			return errorx.IllegalArgument.New("Controller has been already assigned")
    34  		}
    35  		r.controllerFactory = fn
    36  		return nil
    37  	}
    38  }
    39  
    40  // WithDefaultRPCController is an Option to set Runner controller to default rpc.Controller
    41  func WithDefaultRPCController() Option {
    42  	return WithController(func(m *metrics.Metrics, c *config.Config, l *slog.Logger) (node.Controller, error) {
    43  		if c.RPC.Implementation == "none" {
    44  			return node.NewNullController(l), nil
    45  		}
    46  
    47  		return rpc.NewController(m, &c.RPC, l)
    48  	})
    49  }
    50  
    51  // WithDisconnector is a an Option to set Runner disconnector
    52  func WithDisconnector(fn disconnectorFactory) Option {
    53  	return func(r *Runner) error {
    54  		r.disconnectorFactory = fn
    55  		return nil
    56  	}
    57  }
    58  
    59  // WithBroadcaster is an Option to set Runner broadaster
    60  func WithBroadcasters(fn broadcastersFactory) Option {
    61  	return func(r *Runner) error {
    62  		r.broadcastersFactory = fn
    63  		return nil
    64  	}
    65  }
    66  
    67  // WithDefaultBroadcaster is an Option to set Runner subscriber to default broadcaster from config
    68  func WithDefaultBroadcaster() Option {
    69  	return WithBroadcasters(func(h broadcast.Handler, c *config.Config, l *slog.Logger) ([]broadcast.Broadcaster, error) {
    70  		broadcasters := []broadcast.Broadcaster{}
    71  		adapters := strings.Split(c.BroadcastAdapter, ",")
    72  
    73  		for _, adapter := range adapters {
    74  			switch adapter {
    75  			case "http":
    76  				hb := broadcast.NewHTTPBroadcaster(h, &c.HTTPBroadcast, l)
    77  				broadcasters = append(broadcasters, hb)
    78  			case "redis":
    79  				rb := broadcast.NewLegacyRedisBroadcaster(h, &c.Redis, l)
    80  				broadcasters = append(broadcasters, rb)
    81  			case "redisx":
    82  				rb := broadcast.NewRedisBroadcaster(h, &c.Redis, l)
    83  				broadcasters = append(broadcasters, rb)
    84  			case "nats":
    85  				nb := broadcast.NewLegacyNATSBroadcaster(h, &c.NATS, l)
    86  				broadcasters = append(broadcasters, nb)
    87  			default:
    88  				return broadcasters, errorx.IllegalArgument.New("Unsupported broadcast adapter: %s", adapter)
    89  			}
    90  		}
    91  
    92  		return broadcasters, nil
    93  	})
    94  }
    95  
    96  // WithSubscriber is an Option to set Runner subscriber
    97  func WithSubscriber(fn subscriberFactory) Option {
    98  	return func(r *Runner) error {
    99  		if r.subscriberFactory != nil {
   100  			return errorx.IllegalArgument.New("Subscriber has been already assigned")
   101  		}
   102  		r.subscriberFactory = fn
   103  		return nil
   104  	}
   105  }
   106  
   107  // WithDefaultSubscriber is an Option to set Runner subscriber to pubsub.NewSubscriber
   108  func WithDefaultSubscriber() Option {
   109  	return WithSubscriber(func(h pubsub.Handler, c *config.Config, l *slog.Logger) (pubsub.Subscriber, error) {
   110  		switch c.PubSubAdapter {
   111  		case "":
   112  			return pubsub.NewLegacySubscriber(h), nil
   113  		case "redis":
   114  			return pubsub.NewRedisSubscriber(h, &c.Redis, l)
   115  		case "nats":
   116  			return pubsub.NewNATSSubscriber(h, &c.NATS, l)
   117  		}
   118  
   119  		return nil, errorx.IllegalArgument.New("Unsupported subscriber adapter: %s", c.PubSubAdapter)
   120  	})
   121  }
   122  
   123  // WithShutdowable adds a new shutdownable instance to be shutdown at server stop
   124  func WithShutdownable(instance Shutdownable) Option {
   125  	return func(r *Runner) error {
   126  		r.shutdownables = append(r.shutdownables, instance)
   127  		return nil
   128  	}
   129  }
   130  
   131  // WithBroker is an Option to set Runner broker
   132  func WithBroker(fn brokerFactory) Option {
   133  	return func(r *Runner) error {
   134  		if r.brokerFactory != nil {
   135  			return errorx.IllegalArgument.New("Broker has been already assigned")
   136  		}
   137  		r.brokerFactory = fn
   138  		return nil
   139  	}
   140  }
   141  
   142  // WithWebSocketHandler is an Option to set a custom websocket handler
   143  func WithWebSocketHandler(fn websocketHandler) Option {
   144  	return func(r *Runner) error {
   145  		r.websocketHandlerFactory = fn
   146  		return nil
   147  	}
   148  }
   149  
   150  // WithWebSocketEndpoint is an Option to set a custom websocket handler at
   151  // the specified path
   152  func WithWebSocketEndpoint(path string, fn websocketHandler) Option {
   153  	return func(r *Runner) error {
   154  		r.websocketEndpoints[path] = fn
   155  		return nil
   156  	}
   157  }
   158  
   159  // WithDefaultBroker is an Option to set Runner broker to default broker from config
   160  func WithDefaultBroker() Option {
   161  	return WithBroker(func(br broker.Broadcaster, c *config.Config, l *slog.Logger) (broker.Broker, error) {
   162  		if c.BrokerAdapter == "" {
   163  			return broker.NewLegacyBroker(br), nil
   164  		}
   165  
   166  		switch c.BrokerAdapter {
   167  		case "memory":
   168  			b := broker.NewMemoryBroker(br, &c.Broker)
   169  			return b, nil
   170  		case "nats":
   171  			// TODO: Figure out a better place for this hack.
   172  			// We don't want to enable JetStream by default (if NATS is used only for pub/sub),
   173  			// currently, we only need it when NATS is used as a broker.
   174  			c.EmbeddedNats.JetStream = true
   175  			b := broker.NewNATSBroker(br, &c.Broker, &c.NATS, l)
   176  			return b, nil
   177  		default:
   178  			return nil, errorx.IllegalArgument.New("Unsupported broker adapter: %s", c.BrokerAdapter)
   179  		}
   180  	})
   181  }
   182  
   183  // WithTelemetry enables AnyCable telemetry unless ANYCABLE_DISABLE_TELEMETRY is set
   184  func WithTelemetry() Option {
   185  	return func(r *Runner) error {
   186  		r.telemetryEnabled = os.Getenv("ANYCABLE_DISABLE_TELEMETRY") != "true"
   187  		return nil
   188  	}
   189  }
   190  
   191  // WithLogger set ups a logger for the AnyCable app
   192  func WithLogger(logger *slog.Logger) Option {
   193  	return func(r *Runner) error {
   194  		r.log = logger
   195  		return nil
   196  	}
   197  }