Skip to content

Commit 96d3062

Browse files
committed
Try another way
1 parent 4edd374 commit 96d3062

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

pyomo/contrib/solver/solvers/gurobi_direct.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,8 @@ def __init__(self, owner_cls):
185185
def acquire(self, timeout: Optional[float] = None) -> None:
186186
"""Acquire (or reuse) a shared gurobipy.Env."""
187187
cls = self._cls
188-
if cls._get_env() is not None:
188+
env = cls._ensure_env()
189+
if env is not None:
189190
cls._register_env_client()
190191
return
191192

@@ -264,10 +265,27 @@ def _set_env(cls, env):
264265
cls._gurobipy_env_key = None
265266
else:
266267
if cls._gurobipy_env_key is None:
267-
# Stable per-process key; using id(cls) suffices here.
268268
cls._gurobipy_env_key = id(cls)
269269
_GUROBI_ENV_REGISTRY[cls._gurobipy_env_key] = env
270270

271+
@classmethod
272+
def _ensure_env(cls):
273+
"""
274+
Return a live gurobipy.Env. If current env exists but is closed,
275+
recreate it.
276+
"""
277+
env = cls._get_env()
278+
if env is None:
279+
return None
280+
if not hasattr(env, "_cenv"):
281+
try:
282+
env.close()
283+
except Exception:
284+
pass
285+
env = gurobipy.Env()
286+
cls._set_env(env)
287+
return env
288+
271289
def _is_gp_available(self) -> bool:
272290
try:
273291
# this triggers the deferred import
@@ -454,7 +472,7 @@ def solve(self, model, **kwds) -> Results:
454472

455473
# Acquire a Gurobi env for the duration of solve (opt + postsolve):
456474
with self.license():
457-
env = type(self)._get_env()
475+
env = type(self)._ensure_env()
458476

459477
with capture_output(TeeStream(*ostreams), capture_fd=False):
460478
gurobi_model = gurobipy.Model(env=env)

pyomo/contrib/solver/tests/solvers/test_gurobi_direct.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,21 @@ def test_license_acquire_release(self):
185185
opt = GurobiDirect()
186186
mock_gp = self.mocked_gurobipy()
187187
with unittest.mock.patch(f"{self.MODULE_PATH}.gurobipy", mock_gp):
188-
# Explicit acquire/release should set and clear the shared Env
189-
self.assertIsNone(GurobiDirect._gurobipy_env)
188+
cls = GurobiDirect
189+
# Before acquire - nothing locked
190+
self.assertIsNone(cls._get_env())
191+
self.assertIsNone(cls._gurobipy_env_key)
192+
# Acquire - creates and registers env
190193
opt.license.acquire()
191-
self.assertIsNotNone(GurobiDirect._gurobipy_env)
192-
opt.license.release()
193-
self.assertIsNone(GurobiDirect._gurobipy_env)
194+
try:
195+
env_inst = mock_gp.Env.return_value
196+
self.assertIsNotNone(cls._gurobipy_env_key)
197+
self.assertIs(cls._get_env(), env_inst)
198+
finally:
199+
# Client count hits zero -> env closed and cleared
200+
opt.license.release()
201+
self.assertIsNone(cls._get_env())
202+
self.assertIsNone(cls._gurobipy_env_key)
194203

195204

196205
class TestGurobiDirectInterface(unittest.TestCase):

0 commit comments

Comments
 (0)