2009-09-14 5 views
1

Я пытаюсь использовать run tclhttpd in a slave interpreter, но слегка модифицирован, чтобы работать в tclkit. Код ниже «работает» (я могу нажать http://localhost:8015), но никогда не достигает строки puts внизу, потому что «сервер не возвращается, он входит в [vwait forever]». Но когда я пытаюсь «трюк после 0», например. добавив «после 0» к строке «$ httpd eval $ cmd», сервер не запускается вообще, поэтому я предполагаю, что «ошибки должны обрабатываться bgerror»Как использовать Tcl (inter) bgerror

Однако я не могу найти хорошие примеры того, как использовать bgerror, плюс мои исследования показывают, что в настоящее время конвенция заключается в использовании «interp bgerror». Посмотрите первую пару примеров, возвращенных http://www2.tcl.tk/_/gsearch?S=bgerror; первая ссылка содержит словосочетание «заполнить полезные трюки и примеры использования bgerror», но затем нет образцов, которые я могу различить, как применить, а вторая ссылка завершает «Я заинтересован в примерах, как это предполагается использовать».

package require starkit 
starkit::startup 

set httpd_args [list] 
set httpd [interp create] 
$httpd eval "set argc [llength $httpd_args]" 
set cmdargv "set argv [list $httpd_args ]" 
$httpd eval "set topdir $starkit::topdir" 
$httpd eval $cmdargv 

set cmd [list source [file join $starkit::topdir bin/httpd.tcl]] 
$httpd eval $cmd 

puts "if seeing this controlled has returned" 
+0

Hi George, Почему вы хотите ударить по строке «puts»? Вы хотите регистрировать информацию или хотите управлять ошибками? Я потерян, как вы говорите о путях и bgerror. –

+0

Строка puts просто так, что я могу быть уверен, что после запуска tclhttpd с использованием отдельного интерпретатора я могу выполнить другие действия, несмотря на то, что исходный код tclhttpd заканчивается на «vwait forever». Вы можете игнорировать это, когда дело доходит до использования bgerror. –

ответ

1

Я не совсем понимаю вопрос, который вы задаете. Похоже, ваша цель - запустить HTTP-сервер в одном интерпретаторе, но каким-то образом взаимодействовать с основным интерпретатором. Это правильно? Если да, то что это связано с bgerror?

Знаете ли вы, что, хотя вы используете сервер в отдельном интерпретаторе, это не работает в отдельной теме? То есть вы не можете (*) взаимодействовать с основным интерпретатором, в то время как интерпретатор блокируется vwait.

(*) вы можете, если ваше взаимодействие принимает форму Tk виджетов, которые также используют преимущество цикла событий

А как использовать bgerror, Есть несколько способов, которыми он работает. Механизм по умолчанию вызывает функцию «bgerror», которую вы можете определить, чтобы делать то, что вы хотите. Она принимает одну строку (текст сообщения об ошибке) и делает что-то с ней. Это что-то может быть для печати ошибки в stdout , показать его в диалоговом окне, записать его в файл и т.д.

в качестве примера рассмотрим этот интерактивный сеанс:

% proc bgerror {s} {puts "hey! I caught an error: $s"} 
% # after 30 seconds, throw an error 
% after 30000 {error "this is an error"} 
after#0 
% # after 40 seconds, terminate the event loop 
% after 40000 {set ::done 1} 
after#1 
% # start the event loop 
% vwait ::done 
hey! I caught an error: this is an error 
% # this prompt appears after 40 seconds or so 

Вы также можете зарегистрировать свой собственный обработчик ошибок, как описано в документации «interp bgerror». Это произошло в tcl 8.5, хотя у него был bug, который не был зафиксирован до 8.5.3.

Например:

% set foo [interp create] 
interp0 
% $foo eval {proc myErrorHandler {args} {puts "myErrorHandler: $args"}} 
% $foo bgerror myErrorHandler 
myErrorHandler 
% # after 30 seconds, throw an error 
% $foo eval {after 30000 {error "this is an error"}} 
after#0 
% # after 40 seconds, terminate the loop 
% $foo eval {after 40000 {set ::done 1}} 
after#1 
% $foo eval {vwait ::done} 
myErrorHandler: {this is an error} {-code 1 -level 0 -errorcode NONE -errorinfo {this is an error 
    while executing 
"error "this is an error"" 
    ("after" script)} -errorline 1} 
% # this prompt appears after 40 seconds or so 

ли это поможет ответить на ваш вопрос?

+0

Я не хочу взаимодействовать с slave interpreter, я хочу взаимодействовать с веб-сервером, который он запускает. Я понимаю разницу между ведомым интерпретатором и потоком. Я уверен, что исходная ссылка на http://www2.tcl.tk/8755, которую я опубликовал, весь контекст необходим. Я по существу старался следовать этому «рецепту», он не работал, и в этом случае рецепт предлагает использовать bgerror. –

2

полностью отредактирован на основе замечаний Op по ...

после 0 Хитрость заключается в следующей строке:

after 0 $httpd eval $cmd 

Что это делает сказать интерп, чтобы добавить команду в вопросе ($ http eval $ cmd) в очередь событий, что означает, что он будет запускаться после запуска цикла события (или возврата, если он уже запущен). Вы можете видеть зависимость от цикла событий в следующем комментарии с этой страницы (Jacob Levy):

Следует отметить, что это зависит от того, что цикл событий активен.

Я предполагаю, что вы используете простой Tclsh, что означает, что вы никогда не входите в цикл событий (оболочка Wish входит в цикл событий в конце скрипта, оболочка Tcl не поддерживает). Стандартный способ, чтобы войти в цикл обработки событий, чтобы выполнить следующую команду, как только вы получите в конце кода Tcl:

# Enter the event loop and stay in it until someone 
# sets the "forever" variable to something 
vwait forever 

Это, как говорится, все, что вы не после того, как VWait не будет работать, пока после цикла событий выйдет. Если вы хотите, HTTPD для запуска параллельно кода, вам необходимо либо:

  • Использование нескольких нитей, или написать ... что на самом деле это не так сложно
  • код, который будет основан событие. .. который требует, чтобы вы понимали даже базовое программирование достаточно хорошо, чтобы не допустить, чтобы фрагменты кода были истощены от времени выполнения.

Надеюсь, что это поможет.

+0

Полная команда, которую я пытаюсь начинать «после 0», прямо из связанного с URL-адресом http://www2.tcl.tk/8755: «после 0 $ httpd eval $ cmd» Я хочу запустить сервер, но затем взаимодействовать со всем этим в одном скрипте, предположительно, что делает вышеупомянутый URL-адрес возможным, особенно после того, что они называют «после 0». Я ранее пробовал ваше предложение о выдаче моей собственной команды «vwait forever», извлекая ее из нижней части bin/httpd.tcl. Я предпочел бы внести несколько изменений в базовый источник tclhttpd, как я должен это сделать. –

+0

Оба добавляемых кода «после 0» и «vwait forever» могут (и должны) идти в вашем собственном коде, а не в коде tclhttpd. – RHSeeger

+0

Я ценю информацию в вашем ответе, но я не «принимаю» ее, а вместо этого предлагаю щедрость, поскольку я действительно все еще хочу знать, как использовать bgerror. Я думаю, что это позволит мне узнать разницу между тем, почему я могу запустить сервер без добавления «после 0», хотя я не могу тогда взаимодействовать с ним, и почему сервер не запускает что-либо при использовании трюка «после 0» –

1

Если я правильно понял, что вы хотите сделать, ваш код должен выглядеть так, что:

set httpd_id [thread::create -preserved] 
thread::send $http_id "source [file join $starkit::topdir bin/httpd.tcl]" 

Таким образом, вы будете иметь TclHttpd работает в потоке, не беспокоясь за проблемы VWait

Если вы также хотите получать информацию о любой ошибке во время выполнения httpd, TclHttp отправляет все ошибки в файл журнала. Вы можете настроить путь для ведения журнала:

Log_SetFile "/logs/httpd_log" 

Вам необходимо иметь пакет httpd :: log.

Надеюсь, это поможет.

 Смежные вопросы

  • Нет связанных вопросов^_^