In floating license environments, it could happen that all of the token server's license tokens are in use. If this is the case, no other applications will be able to use Gurobi to solve optimization problems until one of the other tokens is released. In the following, we describe methods for avoiding issues with token server availability. For information on setting up and using a token server, see the documentation.
From the command line, the availability of the token server can be checked with:
However, it is not advisable to parse the output of this command to determine whether a token is available to solve an optimization problem. This is because by the time the output is parsed and code is run to solve a model, there may no longer be any tokens available for use.
Instead of parsing output from gurobi_cl --tokens, applications can interact directly with the token server to determine the availability of tokens. In order to use Gurobi to solve an optimization problem, a Gurobi environment must be constructed. In a floating license environment, the construction of the Gurobi environment requires communication with the token server to determine whether or not any tokens are available for use. If a token is available, it is issued to the Gurobi environment. This environment can then be used to solve optimization problems. The token remains with this Gurobi environment until the environment is destroyed. On the other hand, if no tokens are available when attempting to construct a Gurobi environment, a Gurobi exception is raised and no environment is created.
For example, in gurobipy, a Gurobi environment is created with a call to the Env() constructor:
env = Env('gurobi.log')
If no tokens are available from the token server, a
GurobiError exception is raised:
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "env.pxi", line 48, in gurobipy.Env.__init__ gurobipy.GurobiError: Request denied: use limit (2) exceeded
To avoid such errors, a simple loop with exception handling can be used. The following code snippet will attempt to construct a Gurobi environment once per minute until a token is available. Once a Gurobi environment is successfully created on account of a token being available, the environment can be used to build and solve an optimization problem.
from gurobipy import * import time while True: try: # Attempt to construct a Gurobi environment env = Env('gurobi.log') print("Token retrieved!") break except GurobiError: print("No tokens available...") # Wait 60 seconds time.sleep(60)
This is just a simple example. Is is probably a good idea to limit the number of tries to avoid an infinite loop.
In other modeling frameworks, the same idea applies. All modeling frameworks that facilitate the use of Gurobi must at some point construct a Gurobi environment. For example, in Pyomo, the Gurobi environment is constructed when the model is solved. In a floating license setup, Pyomo raises a pyutilib.common.ApplicationError exception if the model could not be constructed due to the lack of an available token. Thus, the previous code snippet can be modified to continually attempt to solve a Pyomo model every 60 seconds until a token is available:
from pyomo.environ import * from pyutilib.common import ApplicationError import time # "Simple model" from Pyomo documentation model = ConcreteModel() model.x = Var([1,2], domain=NonNegativeReals) model.obj = Objective(expr = 2*model.x + 3*model.x) model.constraint1 = Constraint(expr = 3*model.x + 4*model.x >= 1) opt = SolverFactory('gurobi') while True: try: # Attempt to solve the model # This is where Pyomo attempts to construct a Gurobi environment results = opt.solve(model) model.display() break except ApplicationError: print("No tokens available...") # Wait 60 seconds time.sleep(60)
Please note that the token server does not queue requests, and it is not advisable to flood the server with requests in order to retrieve the next free token. Doing so can easily create a lot of unnecessary network traffic. It may be preferable to increase the number of tokens rather than work around several different applications fighting over a small number of available tokens.