FCO / Red

A WiP ORM for Raku

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Emitted events set is incomplete.

vrurg opened this issue · 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.

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.

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?

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.

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

@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.