PoolingModesModal.tsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import { useParams } from 'common'
  2. import { AlertTriangleIcon } from 'lucide-react'
  3. import {
  4. Alert,
  5. AlertDescription,
  6. AlertTitle,
  7. Button,
  8. Dialog,
  9. DialogClose,
  10. DialogContent,
  11. DialogDescription,
  12. DialogFooter,
  13. DialogHeader,
  14. DialogSection,
  15. DialogSectionSeparator,
  16. DialogTitle,
  17. } from 'ui'
  18. import { Markdown } from '@/components/interfaces/Markdown'
  19. import { DocsButton } from '@/components/ui/DocsButton'
  20. import { useSupavisorConfigurationQuery } from '@/data/database/supavisor-configuration-query'
  21. import { DOCS_URL } from '@/lib/constants'
  22. import { useDatabaseSelectorStateSnapshot } from '@/state/database-selector'
  23. import { useDatabaseSettingsStateSnapshot } from '@/state/database-settings'
  24. export const PoolingModesModal = () => {
  25. const { ref: projectRef } = useParams()
  26. const snap = useDatabaseSettingsStateSnapshot()
  27. const state = useDatabaseSelectorStateSnapshot()
  28. const { data } = useSupavisorConfigurationQuery({ projectRef: projectRef })
  29. const primaryConfig = data?.find((x) => x.identifier === state.selectedDatabaseId)
  30. const navigateToPoolerSettings = () => {
  31. const el = document.getElementById('connection-pooler')
  32. if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' })
  33. }
  34. return (
  35. <Dialog open={snap.showPoolingModeHelper} onOpenChange={snap.setShowPoolingModeHelper}>
  36. <DialogContent hideClose className="sm:max-w-4xl">
  37. <DialogHeader>
  38. <DialogTitle>
  39. <div className="w-full flex items-center justify-between">
  40. <p className="max-w-2xl">Which pooling mode should I use?</p>
  41. <DocsButton
  42. href={`${DOCS_URL}/guides/database/connecting-to-postgres#how-connection-pooling-works`}
  43. />
  44. </div>
  45. </DialogTitle>
  46. <DialogDescription className="max-w-2xl">
  47. A connection pooler is a system (external to Postgres) which manages Postgres
  48. connections by allocating connections whenever clients make requests.
  49. </DialogDescription>
  50. </DialogHeader>
  51. <DialogSectionSeparator />
  52. <DialogSection>
  53. <Markdown
  54. className="max-w-full [&>h3]:text-sm"
  55. content={`
  56. Each pooling mode handles connections differently.
  57. ### Transaction mode
  58. This mode is recommended if you are connecting from *serverless environments*. A connection is assigned to the client for the duration of a transaction. Two consecutive transactions from the same client could be executed over two different connections. Some session-based Postgres features such as prepared statements are *not available* with this option.
  59. ### Session mode
  60. This mode is similar to connecting to your database directly. There is full support for prepared statements in this mode. When a new client connects, a connection is assigned to the client until it disconnects. You *might run into pooler connection limits* since the connection is held till the client disconnects.
  61. ### Using session and transaction modes at the same time
  62. ${
  63. primaryConfig?.pool_mode === 'transaction'
  64. ? 'You can use the session mode connection string (port 5432) and transaction mode connection string (port 6543) in your application.'
  65. : 'To get the best of both worlds, as a starting point, we recommend using session mode just when you need support for prepared statements and transaction mode in other cases.'
  66. }
  67. `}
  68. />
  69. </DialogSection>
  70. {primaryConfig?.pool_mode === 'session' && (
  71. <div className="px-6">
  72. <Alert variant="warning">
  73. <AlertTriangleIcon strokeWidth={2} />
  74. <AlertTitle>Pooling mode is currently configured to use session mode</AlertTitle>
  75. <AlertDescription>
  76. To use transaction mode concurrently with session mode, change the pooling mode to
  77. transaction first in the{' '}
  78. <span
  79. tabIndex={0}
  80. className="text-foreground cursor-pointer underline underline-offset-2"
  81. onClick={() => {
  82. snap.setShowPoolingModeHelper(false)
  83. navigateToPoolerSettings()
  84. }}
  85. >
  86. connection pooling settings
  87. </span>
  88. . After this, you can use transaction mode on port 6543 and session mode on port
  89. 5432.
  90. </AlertDescription>
  91. </Alert>
  92. </div>
  93. )}
  94. <DialogFooter>
  95. <DialogClose onClick={() => snap.setShowPoolingModeHelper(false)}>
  96. <Button type="default">Close</Button>
  97. </DialogClose>
  98. </DialogFooter>
  99. </DialogContent>
  100. </Dialog>
  101. )
  102. }