Реализация обработки событий

john.brown

просто кулибин
Реализация обработки событий

Доброго времени суток.
Вот есть какая не то система, в ней модули, сушности, всякое такое. Ну и вобщем удобно массу вещей делать по событиям - удаляем какую то сушность и по beforeDelete удаляем связанные сушности, а по afterDelete пишем стат, что удалили... Вобшем, кучу полезных вещей можно делать. Вопрос об реализации обработки событий. Мне представляется два варианта:

1) какая то сушность генерит событие ( $this->api->events->fire($event)), некий центральный эвент манагер извлекает данные об прикрепленных слушателях, и, соответственно, вызывает их.
PHP:
class core_event_Manager extends core_BaseClass {
	...
	public function fire($event) {
		$sender = $event->getSender();		
		$eventType = $event->getType();
		$listeners = $this->api->registry->get('Events/'.$eventType.'/'.$sender);
		if(!$listeners) return;
		foreach($listeners as $listener) {			
			if(is_callable(array($listener, $eventType))) {				
				call_user_func(array($listener, $eventType), $event);
			}
		}			
	}
}
Так оно у меня счас реализовано, все вроде просто и логично. Токмо вот гемморой с отслеживанием регистрации слушателей - при установке/удалении каких не то частей приложения...

2) эвент манагер просто просматривает эвент хэндлеры всех модулей, на предмет подходящего ообработчика, и вызывает его. А обработчик уже сам решает, обрабатывать, или пропустить. Как то так:
PHP:
class core_event_Manager extends core_BaseClass {
	...
	public function fire($event) {
		$eventType = $event->getType();
                foreach($this->eventHandlers as $handler) {
			if(is_callable($handler, $eventType)) {
				call_user_func(array($handler, $eventType), $event);
			}
		}
	}
}

class some_module_EventHandler {
	...
	public function onBeforeDelete($event) {
		$sender = $event->getSender();
        switch($sender) {
			case 'some_ClassName':
				// делаем что-то
				break;
			default:
				// не делаем ничего
		}
	}
}
Польза очевидна в том, что никакого отслеживания регистра слушателей, типа, все организуется само собой. Вот токмо вопрос, не очень ли ресурсоемком будет такое неограниченное распространение событий через все приложение?

Вобщем, хотел бы слышать какие не то мысли по этому поводу.
 
Токмо вот гемморой с отслеживанием регистрации слушателей
в чем заключается гемморой, если слушатель сам будет подписыватся на определенные события у менеджера?
 
Сам он зарегистрируется если вся тусовка с событиями происходит в пределах обработки одного запроса - т.е. что загружено, то и слушает. А надо, чтоб "слушали" и те части, которые в обработке конкретного запроса никакого участия изначально не принимали, и токмо по событию подгружается и отрабатывает свое. Т. е. надо где то хранить бд слушателей, и отслеживать ее актуальность.
 
Все еще не понимаю, в чем проблема.
надо где то хранить бд слушателей, и отслеживать ее актуальность.
Зачем? Кто подписался - тот и актуален. Не подписался - не актуален. Подписался, но не существует? Ну и хрен с ним, все равно ничего не сделаешь, пропускаем.
 
не очень ли ресурсоемком будет такое неограниченное распространение событий через все приложение
зависит от архитектуры приложений. если не упираемся в желяку и масштабируемся - то пофиг.

если упираемся в железо, то ничего лучше

PHP:
<?php

print "hello!";

?>

я не встречал
 
440hz
Ну вобщем ты прав. Надо сделать, и потом в профиле посмотреть, чего оно берет. Вернуть обретно за всегда моно :)
 
имхо подписчики делятся на тех, кто загрузился, и system wide
если не загружен кто-то из system wide, а событие произошло, загружается и обрабатывает событие
 
weregod
Я с тобой согласен, и как раз о system wide подписчиках и реч. Весь вопрос, хранить их явно в какой то базе, или нет :)

Я тут подумал, и пришел к выводу, что хрен редьки не слаще - если их не хранить в базе, то все равно придется отслеживать, токмо уже в коде, что, имхо, еще хуже. Вот не получаеться как то так сделать, чтоб все оно само происходило... А так хочется... :)
 
Сверху