Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interrupt a running operation #508

Closed
wants to merge 3 commits into from
Closed

Conversation

rheilek
Copy link
Contributor

@rheilek rheilek commented Jan 30, 2024

Using context.WithCancel a call to the cancel func should interrupt the running operation (code snippet below).

ctx, cancel := context.WithCancel(context.Background())
		
go func () {
	fmt.Println(db.ExecContext(ctx, "begin for i in 1..120 loop dbms_lock.sleep(1); end loop; end;"))
}()

go func() {
	time.Sleep(1 * time.Second)
	cancel()
}()

To get it work i disable Urgent-Data-Transport (OOB) because sendOOB on windows is empty. Furthermore oracle-jdbc-driver and nodejs-thin-driver in my debug cases only (can) send marker packets.

The main challenge is the race conidtion between the running operation (read) and another concurrent read from BreakConnection. That's why i simplify the code with returning an error instead of reading the ORA-01013 packet.

@sijms
Copy link
Owner

sijms commented Jan 31, 2024

first thank you for your help also the option of cancelling OOB
but there are 2 point here
1- in connection break function: you discard returned data from the server and return connection break error but this data is important and contain cursor ID required to close the cursor otherwise cursor leak issue will come back
2- you make a go routine for connect context what about exec and query?

@rheilek
Copy link
Contributor Author

rheilek commented Feb 1, 2024

2 - good point, i moved the code to session.StartContext and returning the channel to close with defer

1 - returning an error on BreakConnection was wrong, now only write the packet because the running session.read already read the packet and will handle the ORA-01013.

pck, err := session.readPacket() // hangs and continue after BreakConnection writeMarkerPacket
if err != nil {
	if e, ok := err.(net.Error); ok && e.Timeout() {
		var breakErr error
		tracer.Print("Read Timeout")
		breakErr = session.BreakConnection(true)
		if breakErr != nil {
			//return nil, err
			tracer.Print("Connection Break With Error: ", breakErr)
			return nil, err
		}
	} else {
		return nil, err
	}
}

if session.IsBreak() {
	for pck == nil {
		pck, err = session.readPacket() // reads the response of marker packet

@sijms
Copy link
Owner

sijms commented Feb 2, 2024

your model is good but I need to use it for all context type (cancel and timeout)
timeout is an old problem and passes with many issue until reach this code model
so changing the code need more testing

@sijms
Copy link
Owner

sijms commented Feb 14, 2024

I use your code make some modification and testing. now available in v 2.8.8

@sijms sijms closed this Feb 14, 2024
@rheilek rheilek deleted the interrupt branch February 15, 2024 11:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants