Ордена ленина институт прикладной математики им. М. В. Келдыша Российской Академии Наук

Вид материалаДокументы
4.Пример практического использования механизмов синхронизации
Список литературы
Подобный материал:
1   2   3   4   5   6

4.Пример практического использования механизмов синхронизации



В настоящем разделе будет рассмотрен пример использования описанных нами программных механизмов при решении задач синхронизации поведения DHTML-компонент в реальном проекте. Система разработана в 2005 году по заказу НП «АТС» для проведения учебных биржевых торгов фьючерсными контрактами на поставку электроэнергии и использовалась в методических целях для апробации правил торговли и ознакомления с ними участников рынка.

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





Терминал представляет собой окно броузера (главное окно приложения), поделенное на два вложенных фреймовых окна. В левом окне (управляющей панели) выводится список торгуемых инструментов (контрактов). С помощью checkbox’ов в этой панели трейдер может выбрать инструменты, с которыми он собирается работать.В правом окне фрейма (рабочей панели) отображаются мини-окна, представляющие информацию по состоянию торгов выбранного инструмента. Мини-окна инструментов реализованы при помощи обычных html-элементов
. Трейдер может свободно перемещать мини-окна внутри рабочей панели и управлять их размерами (шириной и высотой). Каждое из мини-окон можно закрыть, либо нажав на нем кнопку [х], либо сняв отметку в checkbox’е соответствующего инструмента в управляющей панели. При завершении работы с торговым терминалом в хранилище броузера (persist store или cookies) сохраняется его визуальное состояние: список всех торгуемых в текущей сессии инструментов; список инструментов, отображаемых в мини-окнах; местоположение и размеры мини-окон и пр.

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

Особенность инициализации терминала заключается в том, что порядок, в котором отрабатываются эти запросы, может быть самым произвольным и промежуток времени от завершения первого из них до выполнения последнего может быть большим (до 10 секунд и даже больше). Это зависит от объема передаваемых с сервера данных: если данных мало (особенно когда это первая сессия трейдера), то первый запрос скорее всего выполнится раньше остальных. Однако более типична ситуация, когда данные будут получены с большой задержкой по отношению к инициализации фреймовых окон. Нельзя исключать и тот случай, когда данные вклинятся между фреймовыми окнами.

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

Реализация такого поведения системы на фазе инициализации представляет собой настоящую головоломку, которая однако легко решается с помощью предложенного инструментария. Для этого на начальной фазе инициализации, после того, как из хранилища броузера прочитаны данные о предыдущем визуальном состоянии терминала, означим переменную приложения $arrInstruments полученным списком инструментов ['WWSCE44-050',...]. Дополнительно для каждого инструмента из этого списка введем переменную, которая принимает значение true, если инструмент выбран, и false в противном случае. Например, для инструмента с кодом 'WWSCE44-050' используем переменную $opened_WWSCE44-050' и, если этот инструмент был выбран, воспользуемся вызовом функции appvarSet(‘$opened_WWSCE44-050', true).

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





Аналогичным образом можно добавить триггер в рабочую панель, который будет поддерживать соответствующий текущему списку инструментов набор мини-окон.

Теперь перейдем к реализации операций добавления и удаления инструментов в меню управляющей панели (функции addMenuItem и removeMenuItem). Операция добавления связана со вводом в обращение новых инструментов, а операция удаления касается инструментов, исключенных из торгов. Здесь возникает задача синхронизации между компонентами левой и правой панели, поскольку инструмент может быть закрыт не только с помощью checkbox’а, но также по кнопке [х] в мини-окне рабочей панели; кроме того надо синхронизовать «видимость» мини-окон с состоянием checkbox’ов. При этом следует помнить, что правая и левая панель загружаются асинхронно.

Для решения указанных задач у нас фактически все есть, поскольку введены переменные приложения, отражающие текущее состояние «выбранности» инструментов. Для актуализации значений этих переменных с элементом checkbox, создаваемым в ходе выполнения функции addMenuItem, следует привязать к этому элементу обработчик:





Кроме того, из функции addMenuItem следует породить динамический триггер, который будет реагировать на изменение значения переменной $opened_WWSCE44-050 и выставлять свойство checkbox.checked в соответствующее значение (например, если инструмент исключается из выбранных путем закрытия мини-окна в рабочей панели, то свойство checkbox.checked примет значение false и в управляющей панели с инструмента снимется отметка):


createTrigger(”trigger_WWSCE44-050”,

‘var eChk = window.document.’+

‘getElementById(”checkbox_WWSCE44-050”);\n’+

‘ eChk.checked = $opened_WWSCE44-050;’);


При реализации функции removeMenuItem, удаляющей инструмент из меню, надо не забыть удалить все созданные динамические фрагменты mvc.phpl

[12] G. Krasner and S. Pope. “A description of the model-view-controller user interface paradigm in the smalltalk-80 system”. Journal of Object Oriented Programming, 1(3):2649, 1988

[13] A. J. Dix, “Status and events: static and dynamic properties of interactive systems.” Proceedings of the Eurographics Seminar: Formal Methods in Computer Graphics, Ed. D. A. Duce. Marina di Carrara, Italy, 1991.

[14] G.D.Abowd and A.J.Dix. “Integrating status and event phenomena in formal specifications of interactive systems.” In Proc. of the ACM SIGSOFT'94 Symposium on the Foundations of Software Engineering, New Orleans, Louisiana, December 1994.

[15] JFC/Swing, com/products/jfc/

[16]Amy Fowler, “A Swing Architecture Overview”

com/products/jfc/tsc/articles/architecture/

[17] Ali Mesbah, K. Broenink and Arie van Deursen. «SPIAR: an architectural style for single page internet applications.», Technical Report SEN-R0603, CWI, 2006.

[18] "The XMLHttpRequest Object", W3C Working Draft 19 June 2006

g/TR/XMLHttpRequest/

[19] W3C Web APIs Working Group

g/2006/webapi/