Skip to content

Commit 4cb5f8e

Browse files
authored
Support interrupting the MIP solver (#229)
1 parent f8052b4 commit 4cb5f8e

File tree

3 files changed

+33
-5
lines changed

3 files changed

+33
-5
lines changed

src/MOI_wrapper/MOI_callbacks.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,11 @@ function MOI.set(model::Optimizer, ::CallbackFunction, callback::Function)
2727
model.has_generic_callback = true
2828
_set_callback(model, (cb_data) -> begin
2929
model.callback_state = _CB_GENERIC
30-
callback(cb_data)
31-
model.callback_state = _CB_NONE
30+
try
31+
callback(cb_data)
32+
finally
33+
model.callback_state = _CB_NONE
34+
end
3235
end)
3336
return
3437
end

src/MOI_wrapper/MOI_wrapper.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1402,7 +1402,9 @@ function _solve_mip_problem(model::Optimizer)
14021402
#
14031403
# This next bit is _very_ important! See the note associated with
14041404
# set_callback.
1405-
if model.callback_data.exception !== nothing
1405+
if model.callback_data.exception isa InterruptException
1406+
model.solver_status = GLP_ESTOP
1407+
elseif model.callback_data.exception !== nothing
14061408
throw(model.callback_data.exception)
14071409
end
14081410
finally

test/MOI_callbacks.jl

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212

1313
module TestCallbacks
1414

15-
using GLPK, Test, Random
15+
using GLPK
16+
using Random
17+
using Test
1618

17-
const MOI = GLPK.MOI
19+
import MathOptInterface as MOI
1820

1921
function runtests()
2022
for name in names(@__MODULE__; all = true)
@@ -554,6 +556,27 @@ function test_issue_189(cache)
554556
return
555557
end
556558

559+
function test_no_cache_InterruptException()
560+
model = GLPK.Optimizer()
561+
MOI.set(model, MOI.Silent(), true)
562+
x = MOI.add_variable(model)
563+
MOI.add_constraint(model, 1.0 * x, MOI.GreaterThan(2.0))
564+
MOI.add_constraint(model, x, MOI.Integer())
565+
MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
566+
f = 1.0 * x
567+
MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f)
568+
interrupt_thrown = false
569+
function my_callback(cb_data)
570+
interrupt_thrown = true
571+
return throw(InterruptException())
572+
end
573+
MOI.set(model, GLPK.CallbackFunction(), my_callback)
574+
MOI.optimize!(model)
575+
@test interrupt_thrown
576+
@test MOI.get(model, MOI.TerminationStatus()) == MOI.INTERRUPTED
577+
return
578+
end
579+
557580
end
558581

559582
TestCallbacks.runtests()

0 commit comments

Comments
 (0)