NewClient returns a client to the Redis Server specified by Options. Passing nil Options will cause a panic.
(opt *Options)
| 1346 | // NewClient returns a client to the Redis Server specified by Options. |
| 1347 | // Passing nil Options will cause a panic. |
| 1348 | func NewClient(opt *Options) *Client { |
| 1349 | if opt == nil { |
| 1350 | panic("redis: NewClient nil options") |
| 1351 | } |
| 1352 | // clone to not share options with the caller |
| 1353 | opt = opt.clone() |
| 1354 | opt.init() |
| 1355 | |
| 1356 | // Push notifications are always enabled for RESP3 (cannot be disabled) |
| 1357 | |
| 1358 | c := Client{ |
| 1359 | baseClient: &baseClient{ |
| 1360 | opt: opt, |
| 1361 | onClose: &onCloseHooks{}, |
| 1362 | }, |
| 1363 | } |
| 1364 | c.init() |
| 1365 | |
| 1366 | // Initialize push notification processor using shared helper |
| 1367 | // Use void processor for RESP2 connections (push notifications not available) |
| 1368 | c.pushProcessor = initializePushProcessor(opt) |
| 1369 | // set opt push processor for child clients |
| 1370 | c.opt.PushNotificationProcessor = c.pushProcessor |
| 1371 | |
| 1372 | // Generate unique pool names for metrics |
| 1373 | uniqueID := generateUniqueID() |
| 1374 | mainPoolName := opt.Addr + "_" + uniqueID |
| 1375 | pubsubPoolName := opt.Addr + "_" + uniqueID + "_pubsub" |
| 1376 | |
| 1377 | // Create connection pools |
| 1378 | var err error |
| 1379 | c.connPool, err = newConnPool(opt, c.dialHook, mainPoolName) |
| 1380 | if err != nil { |
| 1381 | panic(fmt.Errorf("redis: failed to create connection pool: %w", err)) |
| 1382 | } |
| 1383 | c.pubSubPool, err = newPubSubPool(opt, c.dialHook, pubsubPoolName) |
| 1384 | if err != nil { |
| 1385 | panic(fmt.Errorf("redis: failed to create pubsub pool: %w", err)) |
| 1386 | } |
| 1387 | |
| 1388 | if opt.StreamingCredentialsProvider != nil { |
| 1389 | c.streamingCredentialsManager = streaming.NewManager(c.connPool, c.opt.PoolTimeout) |
| 1390 | c.connPool.AddPoolHook(c.streamingCredentialsManager.PoolHook()) |
| 1391 | } |
| 1392 | |
| 1393 | // Initialize maintnotifications first if enabled and protocol is RESP3 |
| 1394 | if opt.MaintNotificationsConfig != nil && opt.MaintNotificationsConfig.Mode != maintnotifications.ModeDisabled && opt.Protocol == 3 { |
| 1395 | err := c.enableMaintNotificationsUpgrades() |
| 1396 | if err != nil { |
| 1397 | internal.Logger.Printf(context.Background(), "failed to initialize maintnotifications: %v", err) |
| 1398 | if opt.MaintNotificationsConfig.Mode == maintnotifications.ModeEnabled { |
| 1399 | /* |
| 1400 | Design decision: panic here to fail fast if maintnotifications cannot be enabled when explicitly requested. |
| 1401 | We choose to panic instead of returning an error to avoid breaking the existing client API, which does not expect |
| 1402 | an error from NewClient. This ensures that misconfiguration or critical initialization failures are surfaced |
| 1403 | immediately, rather than allowing the client to continue in a partially initialized or inconsistent state. |
| 1404 | Clients relying on maintnotifications should be aware that initialization errors will cause a panic, and should |
| 1405 | handle this accordingly (e.g., via recover or by validating configuration before calling NewClient). |