HomeLispLib и WEB

В начале работы над проектом автор обнаружил в Интернете любопытный материал [8]. В нем описывалась реализация Лиспа для целей обучения и планировалось ее использование как в виде настольного приложения, так и в виде ActiveX-компонента, выполняемого на WEB-странице. Тогда у автора возникла мысль о том, чтобы попытаться запустить HomeLisp как серверное WEB-приложение. Запускать HomeLisp как клиентское приложение браузера представляется автору, мягко говоря, не очень плодотворным... А вот используя HomeLisp как серверное WEB-приложение, можно построить учебный класс, в котором на клиентских рабочих местах используются маломощные компьютеры, а все вычисления происходят на сервере. На нем же и инсталлируется HomeLisp в виде WEB-компоненты.

О г л а в л е н и е
Что такое Web-компонента и как она работает.
Настройка Web-компоненты.
Интерфейс конечного пользователя при работе с Web-компонентой.
Дополнительные возможности авторизованного пользователя.
Завершение сеанса.
Администрирование Web-компоненты.
Как устроено рабочее пространство пользователя.
Сообщения об ошибках Web-компоненты.
Что такое WEB-компонента и как она работает.

Первоначально разработчик полагал, что наиболее простым решением будет создание библиотеки ActiveX-Dll, включающей всю необходимую функциональность HomeLisp. Из этой библиотеки предполагалось создавать объект в серверном скрипте (с использованием функции CreateObject) и вызывать из скрипта свойства и методы этого объекта.

Задача оказалась заметно сложнее, чем вначале показалось автору. Дело в том, что HomeLisp весьма требователен к ресурсам процессора и, особенно, к стековому пространству (рекурсия, однако...). Один объект создавать еще кое-как удавалось, а вот со вторым уже возникали проблемы - ведь WEB-сервер должен в основном не вычислять, а отвечать на запросы пользователей. А что произойдет, если программа пользователя зациклится (для обучающихся Лиспу - ситуация нередкая)? Зациклившаяся программа одного пользователя завесит весь WEB-сервер, что абсолютно недопустимо.

Короче говоря, cтало очевидно, что HomeLisp нужно запускать не в простанстве WEB-сервера, а как самостоятельный процесс в отдельном адресном простанстве. В принципе, это вполне резонный подход, - именно так до сих пор работают т.н. CGI-программы. Но и здесь разработчика подстерегала проблема...

Классическая CGI-программа работает так: получив входные параметры (из переменых окружения или стандартного ввода), программа выполняет обработку и завершается. Следующий вызов программы вновь начинается "с чистого листа". Описанная ситуация является печальным следствием особенности протокола HTTP (протокол без сохранения состояния). Обычно этот очевидный недостаток HTTP-протокола исправляется посредством файлов COOKIES (которые передаются в заголовке http-запроса и хранят информацию, которую следует помнить до конца сеанса). Совершенно очевидно, что для Лисп-машины такой сценарий крайне нерационален:

При вычислении каждого S-выражения придется заново загружать весь набор стандартных функций, а также функций, созданных пользователем в течение сеанса. Размер этого блока информации превышает 10Кб. Создание COOKа размером в 10 и более Кб, представляется автору несколько нерациональным...

Вычисление каждого S-выражения будет предваряться инициализацией ядра Лиспа и загрузкой библиотеки. Это снизит среднюю производительность в десятки раз.

Все сказанное выше привело автора к тому, что:

Обслуживания каждого пользователя, должно выполняться в рамках отдельного изолированного процесса (существующего в системе в течение всего сеанса работы, а не завершающегося после каждого запроса, как CGI-программа). Этот процесс (ядро Лиспа) будет, естественно, сохранять состояние в течение всего сеанса с пользователем (ядро инициализируется один раз при запуске и библиотека загружается тоже один раз; функции, созданные пользователем "живут" в ядре и могут быть сохранены вызовом WRS;

Взимодействие ядра Лиспа с активным скриптом на WEB-сервере должно выполняться каким-либо подходящим методом межпроцессорного взаимодействия (в ОС Windows их масса!).

Запуск HomeLisp для каждого пользователя в отдельном процессе предотвращает зависание WEB-сервера и обеспечивает изолированность пользователей друг от друга. Но, к сожалению, имеется еще одна проблема...

Что, произойдет, если пользователь просто закроет окно своего браузера? Браузер закроется, а процесс HomeLisp останется (и будет занимать оперативную память - превратится в процесс-сироту). Следовательно, нужен механизм, в соответствии с которым, процесс HomeLisp, запущенный на сервере, "узнавал", что браузер закрыл обмен.

Автор приял следующее решение: в активном скрипте создается т.н. коммуникационный объект (из входящей в поставку HomeLisp библиотеки Tpw.Dll). Коммуникационный объект запускает исполняемый модуль HomeLispWeb.exe и устанавливает с ним связь, используя именованные каналы (pipes). У объекта, создаваемого из библиотеки Tpw.Dll, есть метод отправки команды HomeLisp и метод получения отклика. Данные, получаемые с формы ввода главной страницы, передаются "своему" экземпляру ядра HomeLisp, после чего коммуникационный объект дожидается ответа ядра. Полученный ответ отображается средствами HTML. Если время ожидания ответа превысило некое граничное значение, то скрипт считает, что ядро HomeLisp завершилось аварийно. При этом происходит автоматический рестарт ядра.

Если пользователь надолго "задумается" и не будет вводить никаких команд, то ядро может "решить", что пользователь просто закрыл браузер. Чтобы дать возможность пользователю думать столько, сколько требуется, в активном скрипте предусмотрена следующая возможность. Один раз в секунду скрипт посылает ядру сигнал квитирования (короткую условную последовательность байтов). Для ядра прием этого сигнала означает, что клиент работает (браузер не закрыт). Но если ядро не получает сигнала квитирования в течение 20-30 сек, то это означает, что клиент закрыл браузер. В этом случае ядро тоже завершает свою работу. Этот механизм гарантирует отсутствие процессов-сирот на WEB-сервере.

Архитектура получившегося WEB-приложения, описанная выше, показана на следующем рисунке.

Настройка WEB-компоненты.

Для функционирования WEB-компоненты нужно обеспечить наличие на компьютере-сервере WEB-сервера IIS или PWS (персональный WEB-сервер). Здесь не будет описываться в подробностях, как инсталлировать это программное обеспечение, поскольку на эту тему имеется достаточно материалов в Интернете. В системе Win-9x инсталлятор персонального WEB-сервера находится на инсталляционном диске в папке \Add-On. Нужно запустить инсталлятор и отвечать на его вопросы. В системах Win-2k/XP для установки IIS необходимо пройти по цепочке:

Панель управления -> Установка и удаление программ -> Установка компонентов Windows

выбрать "Установка IIS" и отвечать на естественные вопросы (потребуется установочный диск Windows). За подробностями автор отправляет читателя к специальным руководствам.

Итак, далее будем полагать, что в нашем распоряжении имеется правильно настроенный сервер IIS. После установки HomeLisp в целевой директории будет создана поддиректория Web, в которой разместятся все необходимые файлы. Ниже структура и состав поддиректория Web будет подробно описана.

\Dump - в этой директории размещаются снимки списка объектов и ассоциативного списка, которые запрашиваются пользователями во время работы;

\Tmp - в этой директории размещаются протоколы работы пользователей;

\Help - в этой директории размещаются html-файлы документации;

\Lib - в этой директории размещаются файлы автозагружаемых библиотек;

\Pwd - в этой директории размещается парольный файл usertab.txt;

\Img - в этой директории размещается необходимые графические файлы;

В директории Web располагаются файлы с расширением .asp, которые обеспечивают функциональность сайта. Кроме того, в директории Web размещаются:

xCoder.Dll - библиотека кодирования;

Tpw.Dll - библиотека связи IIS с Web-компонентой;

HomeLispWeb.Exe - Web-компонента HomeLisp;

HomeLisp.ini ini-файл Web-компоненты;

Чтобы Web-приложение стало работоспособным, необходимо выполнить три действия:

1) Решить, оставлять директорию \Web на месте или скопировать ее в другое место файловой системы.

2) Приняв окончательное решение о размещении директории \Web (и, при необходимости, выполнив копирование), зарегистрировать библиотеки xCoder.Dll и Tpw.Dll, выполнив команды: regsvr32 xCoder.Dll и regSvr32 Tpw.Dll.

3) Войти в режим администрирования сервера IIS и создать виртуальную директорию, указав в качестве реальной директории путь к окончательному месторасположению директории \Web.

Дальнейшее изложение будет вестись применительно к Win2K/XP. Для Win9x последовательность создания виртуального каталога несколько иная. Пользователей Win9x автор адресует к специальным руководствам.

Создание виртуальной директории выполняется следующим образом: необходимо пройти по цепочке: Панель управления -> Администрирование -> Internet Information Services. Пользователь увидит т.н. оснастку администрирования IIS:

Необходимо щелкнуть правой клавишей мыши по иконке "Default Web Cite", выбрать в появившемся контекстном меню пункт "Cоздать" и далее - "Виртуальный каталог":

После щелчка мыши по надписи "Виртуальный каталог" запустится мастер создания виртуальных каталогов:

Следует нажать кнопку Далее. Пользователю будет предложено задать виртуальное имя (псевдоним) каталога. Именно это имя должны будут вводить в адресной строке браузера пользователи Web-компоненты. Виртуальное имя может быть любым (на приводимом ниже рисунке задано lisp):

Задав виртуальное имя, следует нажать кнопку "Далее" - будет предложено ввести реальное имя директории. Его можно ввести в поле ввода, либо восопользоваться стандартным диалогом выбора папки, нажав кнопку "Обзор":

На приведенном выше рисунке виртуальное имя Lisp приcваивается реальной директории e:\HLWeb. После нажатия кнопки "Далее", потребуется установить Web-права на создаваемую директорию:

Галочки "Чтение" и "Запуск сценариев" должны быть включены. После нажатия кнопки "Далее" мастер создания виртуальных директорий завершает работу:

Если все описанное выше, проделано верно, то при вводе в адресной строке браузера адреса http://bob/lisp (Здесь bob - имя сервера автора; пользователь, естественно, должен задать имя своего сервера) отобразится показанная ниже картинка:

Интерфейс конечного пользователя при работе с Web-компонентой.

Интерфейс пользователя Web-компоненты HomeLisp очень прост - он включает в себя следующие элементы:

Гиперссылку с надписью HomeLisp, с которой связана Help-система;

Панель инструментов с тринадцатью иконками (каждая из которых снабжена контекстной подсказкой). Для пользователя, прошедшего авторизацию, становятся доступными две дополнительные иконки ("сохранить состояние" и "редактор");

Область ввода;

Область ответа;

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

Назначение иконок панели инструментов приводится в следующей таблице:

Иконка Назначение
Выполнить команду из области ввода
Листать протокол "вверх" (от первых команд к последним)
Листать протокол "вниз" (от последних команд к первым)
Очистить протокол
Вызвать сборку мусора (передать ядру HomeLisp команду (GC))
Сформировать снимок списка объектов (передать ядру HomeLisp команду (OBJLIST))
Сформировать снимок ассоциативного списка (передать ядру HomeLisp команду (ASSOLIST)). Снимок ассоциативного списка будет сформирован только в случае, если в ядре имеются атомы-переменные. В противном случае снимок не формируется и выдается предупреждение.
Включить режим статистики (передать ядру HomeLisp команду (STAT))
Включить режим статистики (передать ядру HomeLisp команду (UNSTAT))
Выключить режим дампа (передать ядру HomeLisp команду (UNDUMP*))
Выключить режим дампа (передать ядру HomeLisp команду (DUMP*))
Зарегистрироваться в системе (потребуется ввод логина и пароля).
Завершить работу c HomeLisp.


После того, как Web-компонента выдала приглашение к вводу, пользователь может вводить команды. Команды вводятся в область ввода, расположенной под панелью инструментов с иконками. Пользователь вводит S-выражение и щелкает мышью по иконке с изображением желтой молнии. Если введенное в область ввода S-выражение корректно (скобки и кавычки сбалансированы), то оно передается Web-компоненте, вычисляется, а результат отображается в браузере. Если же выражение некорректно, то пользователю выдается предупреждение, а выражение остается в области ввода для последующей правки.

Рассмотрим ввод команды HomeLisp и получение ответа. Ниже показана введенная пользователем команда, размещенная в области ввода:

Если пользователь щелкнет мышью по желтой молнии, то будет отображен результат:

Как можно убедиться, ответ состоит из нескольких областей - полос. В первой полосе продублирована введенная команда. Вторая полоса содержит результат вычисления введенного S-выражения. Третья полоса содержит статистические сведения: время вычисления (в сек.), количество занятых списочных ячеек, количество атомов (после слэша указано количество переменных) и ориентировочный объем использованной памяти.

Результат запроса снимка ассоциативного списка (щелчком по шестой иконке или вводом команды (OBJLIST)) показан ниже:

В этом случае под полосой статистики расположена гиперссылка для просмотра снимка списка объектов на момент выполнения команды. Если щелкнуть мышью по этой гиперсылке, то можно увидеть снимок списка объектов:

Атомы в списке объектов упорядочены в лексикографическом порядке. В заголовке снимка фиксируется дата и время его создания. Снимок сохраняется в отдельном html-файле на диске; этот файл можно многократно просматривать. После завершения сеанса пользователя файлы снимков удаляются.

Если завести переменные (с использованием функции SET/SETQ), то станет доступен просмотр ассоциативного списка. Для просмотра ассоциативного списка следует щелкнуть по седьмой иконке, - будет сформирована гиперссылка для просмотра ассоциативного списка:

Сам ассоциативный список выглядит так:

Атомы в ассоциативном списке не упорядочиваются по именам, а показываются в порядке их создания.

Если введенное S-выражение использует вывод, т.е. функции PRINT/PRINTLINE, то в браузере вывод представляется отдельной полосой. Так, если пользователь ввел команду

(for i 1 30 ((printline (fact i))))


то результат будет таким:

Если пользователь включил режим статистики (нажав 8-ю иконку панели инструментов или явно введя команду (STAT)), то статистические данные о количестве вызовов функций будут также представлятся отдельной полосой:

Если пользователь включил режим дампирования (нажав 10-ю иконку панели инструментов или явно введя команду (DUMP*)), то в отдельной полосе приводится сылка на снимок дампа:

Сам дамп вычислений можно просмотреть в отдельном окне, щелкнув по ссылке "Просмотр дампа":

Все описанные выше возможности, доступны любому пользователю Web-компоненты. В дополнение к этому, пользователь может пройти авторизацию на сайте. Для этого администратор сайта должен присвоить пользователю логин и пароль. Авторизованному пользователю выделяется отдельное место на жестком диске сервера. Это позволяет пользователю сохранять состояние своей Лисп-машины, а также загружать на сервер и скачивать из своей папки файлы.

Дополнительные возможности авторизованного пользователя.

Чтобы пользователь мог авторизоваться на сайте, администратор должен присвоить пользователю логин и пароль. Для выполнения авторизации пользователь должен щелкнуть мышью по двенадцатой иконке панели инструментов (с изображением ключа), - появится экран ввода пароля:

На приведенном выше рисунке приведена форма авторизации с введенными логином и паролем. Если пароль верен, то при нажатии Enter будет снова отображена главная форма Web-компоненты. Для авторизованного пользователя она имеет вид:

Можно убедиться, что вместо иконки с изображением ключа, появились две дополнительные иконки. Их назначение приводится в следующей таблице:

Иконки Назначение
Сохранить состояние Лисп-машины в рабочей папке пользователя
Вызвать файловый менеджер

При щелчке по иконке с изображением дискеты (сохранение состояния), пользователю будет показана следующая экранная форма:


Пользователь должен в поле ввода, озаглавленном "Описание файла" ввести краткое описание создаваемого файла, а в поле "Имя файла" задать имя файла с расширением lsp. Имя файла не может содержать буквы диска и имен директорий. При щелчке по надписи "Сохранить состояние" в рабочей папке пользователя будет создан файл, содержащий S-выражения, составляющие текущее состояния Лисп-машины пользователя.

Другой способ сохранения состояния заключается в прямом вводе команды WRS:

(WRS "имя_файла" "Описание_файла")

Сохраненное состояние можно затем восстановить из файлового менеджера.

Для вызова файлового менеджера пользователь должен щелкнуть мышью по предпоследней иконке панели инструментов (на ней изображено дерево файлов и папок). Главная форма файлового менеджера имеет вид:

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

Иконка Назначение
Вернуться на главную форму (для ввода S-выражений)
Создать новый файл.
Занести файл в хранилище с внешнего носителя или с жесткого диска клиентского компьютера.
"Листать" список файлов "назад" (от последних файлов к первым).
"Листать" список файлов "вперед" (от первых файлов к последним).
Выгрузить соответствующий файл на внешний носитель.
Редактировать файл.
Удалить файл.

При щелчке по иконке "Cоздать новый файл" открывается окно простого web-редактора, имеющего вид:

Пользователь должен задать имя создаваемого файла (по умолчанию - noname), описание создаваемого файла и ввести содержимое файла:

Теперь следует щелкнуть по иконке с изображением дискеты. Произойдет сохранение файла в рабочей папке пользователя:

Как видно из рисунка, имя файла зафиксировалось. Файл можно редактировать и сохранять многократно. Если теперь вернуться в файловый менеджер (щелкнув по иконке со стрелкой), то можно увидеть, что файл добавился в оглавление:

Теперь, чтобы передать созданный файл ядру Лиспа, нужно просто щелкнуть мышью по названию файла. Будет выдано предупреждение:

После подтверждения загрузки файл будет обработан ядром Лиспа. Можно убедиться, что заданная функция работает предсказуемо: попытка деления на нуль возвращает атом infinite (бесконечность):

Для загрузки файла с внешнего носителя в рабочую папку авторизованного пользователя следует, находясь на главной форме файлового менеджера, нажать кнопу "Обзор" и выбрать нужный файл:

После выбора нужного файла, следует задать его описание, как это показано на приводимом ниже рисунке:

Теперь следует щелкнуть по 3-ей иконке панели инструментов. При успешной загрузке будет выдано сообщение и файл с комментарием добавится в хранилище:

Теперь этот файл можно корректировать и передавать ядру Лиспа для исполнения.

Для выгрузки файла из рабочей папки пользователя на внешний носитель следует щелкнуть по самой левой иконке, расположенной в строке нужного файла. Будет сформирована страница со ссылкой на нужный файл для сохранения. Страница выглядит так:

При щелчке по этой ссылке появится знакомый пользователям Интернета диалог сохранения:

Нажатие кнопки "Сохранить" позволяет сохранить файл на клиентском компьютере (на локальном или сетевом диске, а также на сменном носителе).

Для удаления файла из рабочей папки следует щелкнуть по иконке с изображением красного крестика справа от поля описания файла и подтвердить удаление файла.

Завершение сеанса.

Закрыть сеанс можно, разумеется, просто закрыв окно браузера "крестом". Однако более коррекным способом закрытия сеанса будет щелчок мыши по последней иконке панели инструментов. При этом автоматически гасится процесс ядра Лиспа пользователя, а в браузере отображается вот такая картинка:

Красным выделяется чистое время центрального процессора, которое было потрачено в сеансе пользователя.

Администрирование WEB-компоненты.

Для администрирования WEB-компоненты необходимо в адресной строке браузера браузере ввести адрес:

http://Имя_Сервера/Имя_виртуальной_директории/admin.asp

У автора этого руководства приведенный выше адрес имеет вид:

http://Bob/lisp/admin.asp

Совершенно естественно, что любое администрирование начинается с запроса пароля:


Пусть читатель обратит внимание на то, что имя пользователя (admin) вообще не вводится. При первом запуске следует задать пароль password (строчными буквами). Впоследствии пароль администратора можно изменить (и это рекомендуется сделать!) После ввода пароля следует нажать Enter. Если пароль верен, то будет отображена WEB-страница администрирования:

Красным цветом выделено количество активных пользователей (точнее, число еще не истекших сессий ASP). Ниже каждый из административных режимов будет описан подробнее.

При выборе пункта "Конфигурировать параметры ядра", администратор увидит следующую картинку:

Следует задать/изменить нужные параметры, после чего щелкнуть мышью по надписи Сохранить. При этом старый файл HomeLisp.ini будет сохранен под именем HomeLisp.bak и создан новый файл HomeLisp.ini, содержащий введенне администратором значения параметров.

Особенно следует обратить внимание на параметр "Количество запускаемых экземпляров Web-компоненты". Значение этого параметра следует установить большим на 1-2, чем число предполагаемых рабочих мест. Параметр позволяет принудительно ограничить число процессов, в которых запускается модуль HomeLispWeb.Exe. При попытке запустить большее, чем допустимо, количество Web-компонент, пользователю будет показан следующий экран:

При щелчке по надписи "Попробовать еще раз" - делается попытка запустить экземпляр Web-компоненты. Если количество уже запущенных Web-компонент позволяет запустить еще одну, то она будет запущена. В противном случае пользователю вновь будет показана приведенная выше картинка.

При щелчке по надписи "Добавить пользователя", администратору будет предложено задать логин пользователя, его пароль, а также подтверждение пароля (все, как обычно...):

После заполнения всех полей следует нажать Enter. Если пароль не совпадает с контрольным вводом (содержимое второго поля ввода отлчается от содержимого третьего), то выдается соответствующее предупреждение, а пользователь не создается. Если делается попытка создать уже существующего пользователя, то также выдается сообщение об ошибке. Естественно, что нельзя создать пользователя admin. Если же контроль прошел успешно, новый пользователь будет создан и ему будет выделено рабочее пространство на диске.

При щелчке по надписи "Удалить пользователя", администратору будет показан список всех пользователей (разумеется, кроме администратора):

Чтобы удалить пользователя, следует щелкнуть мышью по его имени и затем подтвердить удаление. При удалении пользователя автоматически удаляется и его рабочее пространство (вместе со всеми файлами).

При щелчке по надписи "Сменить пароль пользователя", администратору будет показан список всех пользователей (включая администратора):

Администратор должен щелчком мыши выбрать нужного пользователя и ввести для него новый пароль и подтверждение нового пароля:

Если все введено верно, пароль у пользователя будет заменен. Режим позволяет заменить пароль и у администратора. Но при замене пароля администратора в целях повышения безопасности нужно будет кроме нового пароля предъявить и старый пароль:

В заключение осталось сказать, что логины и пароли хранятся в файле \Pwd\usertab.txt в зашифрованном виде. Трогать этот файл "руками" не рекомендуется категорически. После переназначения пароля администратора и назначения паролей пользователям желательно сделать копию этого файла в надежном месте.

Как устроено рабочее пространство пользователя.

Рабочее пространство пользователя представляет собой папку с именем usr_Логин. Так, для пользователя Bob имя папки будет usr_Bob. Внутри этой папки располагается следующая информация:


Папка Tmp, в которой хранятся протоколы работы пользователя;

Текстовый файл descript.ion, котором каждая строчка содержит информацию об одном файле, загруженном в рабочее пространство;

Списка файлов вида "_nnnn.lsp", где nnnn - порядковый номер загруженного файла.

Файлы, загружаемые в рабочее пространство пользователя, переименовываются, а их исходные имена (а также длины, даты создания и описания, заданные пользователем) - хранятся в файле descript.ion. Ниже приводится фрагмент файла descript.ion:


0017.lsp;123.lsp;43;12/07/2008 18:32:12;Создание списка-2
0018.lsp;noname.lsp;14;13/07/2008 18:13:49;Вычисляем факториал
0020.lsp;lib-8.lsp;11879;18/07/2008 21:20:29;Версия с mklist
0021.lsp;atest;127;14/10/2009 21:44:15;Тест MKLIST1 и SUMLIST
0022.lsp;test1.lsp;233;14/10/2009 21:50:55;Тест FACT и TRY
0023.lsp;t1.lsp;97;16/10/2009 19:23:36;Проверка работы функции TRY

Можно видеть, что файл _0022.lsp первоначально назывался test1.lsp, имеет длину 233 байта и был загружен 10.10.2009. При загрузке пользователь снабдил этот файл комментарием: "Тест FACT и TRY".

Сообщения об ошибках WEB-компоненты.

Ошибки, которые могут возникать при работе Web-компоненты, можно разделить на две группы:

Ошибки, перехватываемые средой HomeLisp (деление на нуль, попытка вычислить CDR от атома и т.д.). Сообщения о таких ошибках выводятся отдельной полосой в области ответа. Эти ошибки, как правило, не вызывают завершения выполнения HomeLispWeb.exe.

Ошибки, вызывающие завершение выполнения HomeLispWeb.exe. При возникновении таких ошибок пользователю выводится сообщение вида, приведенного ниже, а через 10 сек происходит автоматический рестарт Web-компоненты.

Автор выражает надежду, что подобные ошибки будут возникать чрезвычайно редко (или вообще не будут возникать)...

Сайт создан в системе uCoz