Red icon indicating copy to clipboard operation
Red copied to clipboard

Emitted events set is incomplete.

Open vrurg opened this issue 4 years ago • 5 comments

I'm trying to revive a homebrew project of mine. In the project I'm trying to automate DB management by recording all project tables (models) with their versions and whatever meta info I may need to manage them. The code was written prior to me switching to use of schema() and was based upon overloading create-table method of MetamodelX::Red::Model. Unfortunately, schema works differently, without using the method.

So, I decided that using events would be much better solution. Unfortunately, it is not because creation events are only emitted by create-table, schema doesn't do it.

By looking at the Model create-table code and comparing it to create-schema on CommonSQL I came up with a thought that execute itself must be an event, no matter what kind of query is submitted to it. This would make full sense to me. There would be a little performance cost attached, but I hope it's not too high comparing to the overall cost of DB queries.

vrurg avatar Sep 12 '21 22:09 vrurg

I agree, but we'll need to find a way to make the specific model emit that event. Currently a user can tap events from a specific model, a specific driver or all events.

FCO avatar Nov 08 '21 13:11 FCO

maybe it would just be easier add 2 model.^emit: $ast on create-schema.

we could also do something like for $ast.tables { .^orig.emit: $ast } on execute but on that case, a select would be emitted not only the original model, but also on every model used as join, and a create table would no be emitted only by the table itself, but also by all tables that has a relationship with it. Maybe that would make sense... but I'm still not sure... and we would also have to add an .uniq on the driver and the "all" supply.

@vrurg what do you think about that?

FCO avatar Nov 08 '21 13:11 FCO

Unfortunately, I'm not sufficiently well knows with Red internals. From what I remember, when I was trying to dig down the problem, it seemed to me that more generic solution would be to move the emit into execute internals. In this case only actually executing ASTs would be emitted. This could be costly, on the other hand. But since not everybody needs events they could be turned off altogether. Or filtering could be added, so only certain ASTs of intereset are emitted.

vrurg avatar Nov 08 '21 14:11 vrurg

This is not the way you suggested but it should be enough for now, please let me know if it is.

FCO avatar Dec 29 '21 19:12 FCO

@FCO I wouldn't be able to try to for a while, but looks like it would help me in that original problem. Yet, if somebody would wish to monitor execution of other statements, they may not have the chance to do it.

One idea has just crossed my mind. To reduce the cost of emitting from execute, it is possible to start an emitting thread whenever necessary. Submitting an AST into a channel is faster, than emitting into a supply because the latter is a co-routine and would depend on the user code performance. Whereas with a dedicated thread which receives the ASTs from a channel things will happen asynchronously to the main line.

Moreover, it is even possible to start/stop the thread on demand since the event supply is created one place, you can count the number of supplies created and, by monitoring which ones were closed, how many are still active.

vrurg avatar Dec 30 '21 15:12 vrurg