nsmcp::QuestionService method run (public)
<instance of nsmcp::QuestionService> run handle turn
Defined in /usr/local/ns/tcl/nsmcp/question-service.tcl
Execute a queued conversation turn. Resolve retained owner/provider state, invoke the selected backend and publish completion, failure or cancellation under the mutex.
- Parameters:
- handle (required)
- Retained job or conversation handle; ownership and expiry checks still apply.
- turn (required)
- Retained turn identifier, used to reject superseded callbacks.
- Returns:
- The worker callback result; conversation state retains the outcome.
- Testcases:
- No testcase defined.
Source code: ns_mutex lock ${:mutex} try { if {![nsv_exists ${:store} $handle]} { return } set record [nsv_get ${:store} $handle] if {[dict get $record current] ne $turn} { return } if {[dict get $record status] in {cancelling cancelled}} { set skip true } else { set skip false dict set record status running nsv_set ${:store} $handle $record } set state [dict get $record state] if {[dict exists $record stateEncoding]} { set state [encoding convertfrom utf-8 [zlib decompress $state]] } set backendName [:defaultBackend] if {[dict exists $record backend]} { set backendName [dict get $record backend] } set entry [lindex [dict get $record turns] end] set question [expr {[dict exists $entry backendQuestion] ? [dict get $entry backendQuestion] : [dict get $entry question]}] } finally { ns_mutex unlock ${:mutex} } # A timed-out turn may have started a job without publishing provider # history. Carry its handle explicitly into the next question. if {[dict exists $record browserTimezone]} { append question "\nBrowser timezone context: [dict get $record browserTimezone]. Use this timezone for unspecified time windows and displayed times, unless the question explicitly requests another timezone." } set pendingJobs {} foreach previous [dict get $record turns] { if {![dict exists $previous jobs]} { continue } dict for {jobHandle job} [dict get $previous jobs] { dict set job needsRetrieval [expr {[dict get $previous status] in {failed cancelled} || [dict get $job status] in {queued running}}] dict set pendingJobs $jobHandle $job } } dict for {jobHandle job} $pendingJobs { if {[dict get $job needsRetrieval]} { append question "\nExisting background jobHandle $jobHandle ([dict get $job name]); retrieve it with log_results rather than starting it again." } } set error {} set status cancelled if {!$skip} { if {[catch { [:provider $backendName] run $question $state [list [self] event $handle $turn] } status]} { set error $status set status failed } } ns_mutex lock ${:mutex} try { if {![nsv_exists ${:store} $handle]} { return } set record [nsv_get ${:store} $handle] if {[dict get $record current] ne $turn} { return } if {[dict get $record status] eq "cancelling"} { set status cancelled set error {} } dict set record status $status set last [lindex [dict get $record turns] end] dict set last status $status dict set last error $error if {[dict exists $last submittedMs]} { dict set last elapsedMs [expr {max(0,[clock milliseconds]-[dict get $last submittedMs])}] } :logQuestion finished $record $last dict set record turns [lreplace [dict get $record turns] end end $last] nsv_set ${:store} $handle $record } finally { ns_mutex unlock ${:mutex} }XQL Not present: Generic, PostgreSQL, Oracle
![[i]](/resources/acs-subsite/ZoomIn16.gif)