trovesuite 1.0.29__tar.gz → 1.0.30__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. {trovesuite-1.0.29/src/trovesuite.egg-info → trovesuite-1.0.30}/PKG-INFO +1 -1
  2. {trovesuite-1.0.29 → trovesuite-1.0.30}/pyproject.toml +2 -2
  3. {trovesuite-1.0.29 → trovesuite-1.0.30}/setup.py +1 -1
  4. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/configs/database.py +51 -6
  5. {trovesuite-1.0.29 → trovesuite-1.0.30/src/trovesuite.egg-info}/PKG-INFO +1 -1
  6. {trovesuite-1.0.29 → trovesuite-1.0.30}/LICENSE +0 -0
  7. {trovesuite-1.0.29 → trovesuite-1.0.30}/MANIFEST.in +0 -0
  8. {trovesuite-1.0.29 → trovesuite-1.0.30}/README.md +0 -0
  9. {trovesuite-1.0.29 → trovesuite-1.0.30}/requirements.txt +0 -0
  10. {trovesuite-1.0.29 → trovesuite-1.0.30}/setup.cfg +0 -0
  11. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/__init__.py +0 -0
  12. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/auth/__init__.py +0 -0
  13. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/auth/auth_base.py +0 -0
  14. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/auth/auth_controller.py +0 -0
  15. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/auth/auth_read_dto.py +0 -0
  16. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/auth/auth_service.py +0 -0
  17. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/auth/auth_write_dto.py +0 -0
  18. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/configs/__init__.py +0 -0
  19. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/configs/logging.py +0 -0
  20. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/configs/settings.py +0 -0
  21. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/entities/__init__.py +0 -0
  22. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/entities/health.py +0 -0
  23. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/entities/sh_response.py +0 -0
  24. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/notification/__init__.py +0 -0
  25. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/notification/notification_base.py +0 -0
  26. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/notification/notification_controller.py +0 -0
  27. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/notification/notification_read_dto.py +0 -0
  28. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/notification/notification_service.py +0 -0
  29. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/notification/notification_write_dto.py +0 -0
  30. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/storage/__init__.py +0 -0
  31. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/storage/storage_base.py +0 -0
  32. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/storage/storage_controller.py +0 -0
  33. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/storage/storage_read_dto.py +0 -0
  34. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/storage/storage_service.py +0 -0
  35. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/storage/storage_write_dto.py +0 -0
  36. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/utils/__init__.py +0 -0
  37. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/utils/helper.py +0 -0
  38. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite/utils/templates.py +0 -0
  39. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite.egg-info/SOURCES.txt +0 -0
  40. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite.egg-info/dependency_links.txt +0 -0
  41. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite.egg-info/not-zip-safe +0 -0
  42. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite.egg-info/requires.txt +0 -0
  43. {trovesuite-1.0.29 → trovesuite-1.0.30}/src/trovesuite.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trovesuite
3
- Version: 1.0.29
3
+ Version: 1.0.30
4
4
  Summary: TroveSuite services package providing authentication, authorization, notifications, Azure Storage, and other enterprise services for TroveSuite applications
5
5
  Home-page: https://dev.azure.com/brightgclt/trovesuite/_git/packages
6
6
  Author: Bright Debrah Owusu
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "trovesuite"
7
- version = "1.0.29"
7
+ version = "1.0.30"
8
8
  description = "TroveSuite services package providing authentication, authorization, notifications, Azure Storage, and other enterprise services for TroveSuite applications"
9
9
  authors = ["brightgclt <brightgclt@gmail.com>"]
10
10
  license = "MIT"
@@ -58,7 +58,7 @@ Documentation = "https://dev.azure.com/brightgclt/trovesuite/_git/packages"
58
58
 
59
59
  [project]
60
60
  name = "trovesuite"
61
- version = "1.0.29"
61
+ version = "1.0.30"
62
62
  description = "TroveSuite services package providing authentication, authorization, notifications, Azure Storage, and other enterprise services for TroveSuite applications"
63
63
  readme = "README.md"
64
64
  license = {text = "MIT"}
@@ -15,7 +15,7 @@ with open("pyproject.toml", "r", encoding="utf-8") as fh:
15
15
 
16
16
  setup(
17
17
  name="trovesuite",
18
- version="1.0.29",
18
+ version="1.0.30",
19
19
  author="Bright Debrah Owusu",
20
20
  author_email="owusu.debrah@deladetech.com",
21
21
  description="TroveSuite services package providing authentication, authorization, notifications, and other enterprise services for TroveSuite applications",
@@ -21,10 +21,16 @@ class DatabaseConfig:
21
21
  """Database configuration and connection management"""
22
22
 
23
23
  def __init__(self):
24
+ import os
24
25
  self.settings = db_settings
25
26
  self.database_url = self.settings.database_url
26
- self.pool_size = 5
27
- self.max_overflow = 10
27
+ # CRITICAL: Azure PostgreSQL B_Standard_B1ms has very limited connections (~50 max, practical limit ~30-40)
28
+ # Default pool size is set to 1 to avoid connection exhaustion with multiple workers/replicas
29
+ # Formula: connections = pool_size × workers × replicas
30
+ # Example: 1 pool × 4 workers × 2 replicas = 8 connections (safe)
31
+ # With old default (5): 5 × 4 × 2 = 40 connections (exceeds limit!)
32
+ # Can be overridden with DB_POOL_SIZE environment variable
33
+ self.pool_size = int(os.getenv("DB_POOL_SIZE", "1"))
28
34
 
29
35
  def get_connection_params(self) -> dict:
30
36
  """Get database connection parameters"""
@@ -37,7 +43,7 @@ class DatabaseConfig:
37
43
  "keepalives_idle": 30,
38
44
  "keepalives_interval": 10,
39
45
  "keepalives_count": 5,
40
- "connect_timeout": 10
46
+ "connect_timeout": 30 # Increased timeout for Azure PostgreSQL
41
47
  }
42
48
 
43
49
  # fallback to individual DB_* variables
@@ -57,15 +63,54 @@ class DatabaseConfig:
57
63
  }
58
64
 
59
65
  def create_connection_pool(self) -> psycopg2.pool.ThreadedConnectionPool:
60
- """Create a connection pool for psycopg2"""
66
+ """Create a connection pool for psycopg2
67
+
68
+ Note: For Azure PostgreSQL B_Standard_B1ms, keep pool_size ≤ 1 per worker
69
+ to avoid connection exhaustion. Consider using PgBouncer for higher concurrency.
70
+ """
61
71
  try:
72
+ # For Azure PostgreSQL, use minimum pool size to avoid connection exhaustion
73
+ # Multiple replicas/workers can quickly exhaust database connections on Basic tier
74
+ import os
75
+ dsn = os.getenv("DATABASE_URL", "") or str(self.database_url or "")
76
+ is_azure = "database.azure.com" in dsn.lower()
77
+
78
+ # Ensure pool size is appropriate for Azure Basic tier
79
+ pool_size = self.pool_size
80
+ if is_azure and pool_size > 2:
81
+ logger.warning(
82
+ f"⚠️ Pool size {pool_size} may be too high for Azure Basic tier. "
83
+ f"Recommended: 1-2 connections per worker. "
84
+ f"Set DB_POOL_SIZE=1 to avoid connection exhaustion."
85
+ )
86
+
62
87
  pool = psycopg2.pool.ThreadedConnectionPool(
63
88
  minconn=1,
64
- maxconn=self.pool_size,
89
+ maxconn=pool_size,
65
90
  **self.get_connection_params()
66
91
  )
67
- logger.info(f"Database connection pool created with {self.pool_size} connections")
92
+ logger.info(
93
+ f"Database connection pool created with {pool_size} connections "
94
+ f"(Azure: {is_azure}, DB_POOL_SIZE: {self.pool_size})"
95
+ )
68
96
  return pool
97
+ except psycopg2.OperationalError as e:
98
+ # Check if it's a connection limit error
99
+ error_str = str(e).lower()
100
+ if any(keyword in error_str for keyword in ["connection", "slot", "limit", "exhausted", "too many"]):
101
+ logger.error("⚠️ Database connection limit reached!")
102
+ logger.error(" Possible causes:")
103
+ logger.error(" 1. Too many connections from multiple replicas/workers")
104
+ logger.error(" 2. Pool size too high (DB_POOL_SIZE environment variable)")
105
+ logger.error(" 3. Too many Gunicorn workers (GUNICORN_WORKERS environment variable)")
106
+ logger.error(" 4. Connections not being properly returned to pool")
107
+ logger.error(" Solutions:")
108
+ logger.error(" - Set DB_POOL_SIZE=1 (recommended for Azure Basic tier)")
109
+ logger.error(" - Reduce GUNICORN_WORKERS (default: 4)")
110
+ logger.error(" - Consider using PgBouncer for connection pooling")
111
+ logger.error(" - Upgrade to a higher PostgreSQL tier if needed")
112
+ logger.error(f"Failed to create database connection pool: {str(e)}")
113
+ raise
69
114
  except Exception as e:
70
115
  logger.error(f"Failed to create database connection pool: {str(e)}")
71
116
  raise
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trovesuite
3
- Version: 1.0.29
3
+ Version: 1.0.30
4
4
  Summary: TroveSuite services package providing authentication, authorization, notifications, Azure Storage, and other enterprise services for TroveSuite applications
5
5
  Home-page: https://dev.azure.com/brightgclt/trovesuite/_git/packages
6
6
  Author: Bright Debrah Owusu
File without changes
File without changes
File without changes
File without changes