From: Adriano d. S. F. <adr...@gm...> - 2011-03-22 23:23:37
|
Hi! Current providers code followed the changes I did in trunk for external engines... IAttachment: virtual ITransaction* FB_CARG startTransaction(Status* status, unsigned int tpbLength, const unsigned char* tpb, FB_API_HANDLE api) = 0; PProvider: virtual void FB_CARG attachDatabase(Status* status, IAttachment** ptr, FB_API_HANDLE api, const char* fileName, unsigned int dpbLength, const unsigned char* dpb) = 0; virtual void FB_CARG createDatabase(Status* status, IAttachment** ptr, FB_API_HANDLE api, const char* fileName, unsigned int dpbLength, const unsigned char* dpb) = 0; startTransaction is currently not ok, so look at PProvider methods and forget about transactions for now (it's the same concepts). The yvalve calls the provider passing the address of an IAttachment* and a handle just allocated. Once the engine setups an attachment, it puts it address in *ptr. This is the place which the yvalve uses, so even before attachDatabase returns, the yvalve can be called and access the database. This is not good solution, and now exposes internal ugliness to the API. The "api" parameters means nothing for user code, and a returned IAttachment is clean than an IAttachment** parameter. And this don't solve the problem with autonomous transactions, created inside the engine and used by external engines. To support this, we need new approach. It's the engine who needs to ask the yvalve to register an object and get its handle (yvalve object). But this must not be done directly, since providers could be chained to implement things (say trace provider, log/replay provider). I propose IProviderManagement interface. The yvalve will creates an instance of IProviderManager and will pass it to the factory that creates a provider. So when an provider is created, it receives an yvalve IProviderManagement (or something else that indirectly calls the yvalve object). It will have these kind of methods: - virtual IAttachment* registerAttachment(IAttachment* attachment) = 0; - virtual void freeAttachment(IAttachment* attachment) = 0; registerAttachment receives the engine object and creates and returns an yvalve object. Remember, ProviderManager instance was created by yvalve. freeAttachment receives the yvalve object and makes the yvalve object orphan, that is, all calls on it will not call the engine provider anymore but will return an error. Now how this is going to be used. Say we have: ------------ IAttachment* JrdProvider::attachDatabase(...) { JrdAttachment* attachment = new ...; ... attachment->external = providerManager->registerAttachment(attachment); ... // database triggers will call external code passing an attachment->external runDatabaseTriggers(attachment); return attachment; } Attachment::~Attachment() { providerManager->freeAttachment(this->external); } ------------ Then we solve three problems: 1) API ugliness: unused (by user code) parameters and refcount 2) External access to objects created internally 3) Management of freed objects Actually, we can solve another problem. Note the IStatement method below. The problem is that a dsql_req (IStatement) cannot be reprepared internally, so a new object must be created. // FixMe - prepare must return void, not new statement handle virtual IStatement* FB_CARG prepare(Status* status, ITransaction* tra, unsigned int stmtLength, const char* sqlStmt, unsigned int dialect, unsigned int itemLength, const unsigned char* items, unsigned int bufferLength, unsigned char* buffer) = 0; We can do something like: dsql_req::prepare(...) { dsql_req* newStatement = ...; providerManager->replaceStatement(this->external, newStatement); } Adriano |
From: Alex P. <pes...@ma...> - 2011-03-23 12:42:55
|
On 03/23/11 02:23, Adriano dos Santos Fernandes wrote: > Hi! > > Current providers code followed the changes I did in trunk for external > engines... > > IAttachment: > virtual ITransaction* FB_CARG startTransaction(Status* status, > unsigned int tpbLength, > const unsigned char* tpb, FB_API_HANDLE api) = 0; > > PProvider: > virtual void FB_CARG attachDatabase(Status* status, IAttachment** > ptr, FB_API_HANDLE api, > const char* fileName, unsigned int dpbLength, const unsigned > char* dpb) = 0; > virtual void FB_CARG createDatabase(Status* status, IAttachment** > ptr, FB_API_HANDLE api, > const char* fileName, unsigned int dpbLength, const unsigned > char* dpb) = 0; > > startTransaction is currently not ok, Aahh - I've forgotten that same trick was needed in it. Sorry. Hope we will find soon better solution. > so look at PProvider methods and > forget about transactions for now (it's the same concepts). The yvalve > calls the provider passing the address of an IAttachment* and a handle > just allocated. > > Once the engine setups an attachment, it puts it address in *ptr. This > is the place which the yvalve uses, so even before attachDatabase > returns, the yvalve can be called and access the database. > > This is not good solution, and now exposes internal ugliness to the API. > The "api" parameters means nothing for user code, and a returned > IAttachment is clean than an IAttachment** parameter. In private discussion Dmitry Kovalenko told me the contrary :-) But personally I agree - API in which new objects are returned, not Object** parameter is passed, looks better. > And this don't solve the problem with autonomous transactions, created > inside the engine and used by external engines. To support this, we need > new approach. It's the engine who needs to ask the yvalve to register an > object and get its handle (yvalve object). > > But this must not be done directly, since providers could be chained to > implement things (say trace provider we discussed it and decided it's bad idea > , log/replay provider which must log only external calls > ). > I think that for current attachment (and transaction) external engines must directly use appropriate engine interfaces. Same for transactions created internally. > I propose IProviderManagement interface. The yvalve will creates an > instance of IProviderManager and will pass it to the factory that > creates a provider. So when an provider is created, it receives an > yvalve IProviderManagement (or something else that indirectly calls the > yvalve object). > > It will have these kind of methods: > - virtual IAttachment* registerAttachment(IAttachment* attachment) = 0; > - virtual void freeAttachment(IAttachment* attachment) = 0; > > registerAttachment receives the engine object and creates and returns an > yvalve object. Remember, ProviderManager instance was created by yvalve. > freeAttachment receives the yvalve object and makes the yvalve object > orphan, that is, all calls on it will not call the engine provider > anymore but will return an error. > > Now how this is going to be used. Say we have: > > ------------ > IAttachment* JrdProvider::attachDatabase(...) > { > JrdAttachment* attachment = new ...; > ... > > attachment->external = providerManager->registerAttachment(attachment); > > ... > // database triggers will call external code passing an > attachment->external > runDatabaseTriggers(attachment); > > return attachment; > } > > Attachment::~Attachment() > { > providerManager->freeAttachment(this->external); > } > ------------ > > Then we solve three problems: > 1) API ugliness: unused (by user code) parameters and refcount > 2) External access to objects created internally > 3) Management of freed objects > > Actually, we can solve another problem. Note the IStatement method > below. The problem is that a dsql_req (IStatement) cannot be reprepared > internally, so a new object must be created. > > // FixMe - prepare must return void, not new statement handle > virtual IStatement* FB_CARG prepare(Status* status, ITransaction* tra, > unsigned int stmtLength, const char* sqlStmt, unsigned int dialect, > unsigned int itemLength, const unsigned char* items, > unsigned int bufferLength, unsigned char* buffer) = 0; > > We can do something like: > > dsql_req::prepare(...) > { > dsql_req* newStatement = ...; > providerManager->replaceStatement(this->external, newStatement); > } > Adriano, are you serious that all described here is simpler than proxy objects in engine? :-) |
From: Adriano d. S. F. <adr...@gm...> - 2011-03-23 14:29:16
|
On 23-03-2011 09:42, Alex Peshkoff wrote: > >> so look at PProvider methods and >> forget about transactions for now (it's the same concepts). The yvalve >> calls the provider passing the address of an IAttachment* and a handle >> just allocated. >> >> Once the engine setups an attachment, it puts it address in *ptr. This >> is the place which the yvalve uses, so even before attachDatabase >> returns, the yvalve can be called and access the database. >> >> This is not good solution, and now exposes internal ugliness to the API. >> The "api" parameters means nothing for user code, and a returned >> IAttachment is clean than an IAttachment** parameter. > > In private discussion Dmitry Kovalenko told me the contrary :-) > But personally I agree - API in which new objects are returned, not > Object** parameter is passed, looks better. > >> And this don't solve the problem with autonomous transactions, created >> inside the engine and used by external engines. To support this, we need >> new approach. It's the engine who needs to ask the yvalve to register an >> object and get its handle (yvalve object). >> >> But this must not be done directly, since providers could be chained to >> implement things (say trace provider > > we discussed it and decided it's bad idea > You can decide it for Firebird, but you can't decide it for user. Let user create *plugins*. >> , log/replay provider > > which must log only external calls > Code from external engines *is* external calls. May not make sense for a replay plugin, but it must pass in the yvalve too. > > I think that for current attachment (and transaction) external engines > must directly use appropriate engine interfaces. > Same for transactions created internally. > No, please. Let create good and unified thing, not a lot of specific thing because we don't want to think. >> I propose IProviderManagement interface. The yvalve will creates an >> instance of IProviderManager and will pass it to the factory that >> creates a provider. So when an provider is created, it receives an >> yvalve IProviderManagement (or something else that indirectly calls the >> yvalve object). >> >> It will have these kind of methods: >> - virtual IAttachment* registerAttachment(IAttachment* attachment) = 0; >> - virtual void freeAttachment(IAttachment* attachment) = 0; >> >> registerAttachment receives the engine object and creates and returns an >> yvalve object. Remember, ProviderManager instance was created by yvalve. >> freeAttachment receives the yvalve object and makes the yvalve object >> orphan, that is, all calls on it will not call the engine provider >> anymore but will return an error. >> >> Now how this is going to be used. Say we have: >> >> ------------ >> IAttachment* JrdProvider::attachDatabase(...) >> { >> JrdAttachment* attachment = new ...; >> ... >> >> attachment->external = providerManager->registerAttachment(attachment); >> >> ... >> // database triggers will call external code passing an >> attachment->external >> runDatabaseTriggers(attachment); >> >> return attachment; >> } >> >> Attachment::~Attachment() >> { >> providerManager->freeAttachment(this->external); >> } >> ------------ >> >> Then we solve three problems: >> 1) API ugliness: unused (by user code) parameters and refcount >> 2) External access to objects created internally >> 3) Management of freed objects >> >> Actually, we can solve another problem. Note the IStatement method >> below. The problem is that a dsql_req (IStatement) cannot be reprepared >> internally, so a new object must be created. >> >> // FixMe - prepare must return void, not new statement handle >> virtual IStatement* FB_CARG prepare(Status* status, ITransaction* tra, >> unsigned int stmtLength, const char* sqlStmt, unsigned int dialect, >> unsigned int itemLength, const unsigned char* items, >> unsigned int bufferLength, unsigned char* buffer) = 0; >> >> We can do something like: >> >> dsql_req::prepare(...) >> { >> dsql_req* newStatement = ...; >> providerManager->replaceStatement(this->external, newStatement); >> } >> > > Adriano, are you serious that all described here is simpler than proxy > objects in engine? :-) > I'm *sure* it is. I showed you ~15 lines of code, against addRefs/releases around by Firebird and all-over-the-world users code. And, BTW, it will not crash when the engine is unloaded, like I said in the another message. Adriano |
From: Vlad K. <hv...@us...> - 2011-03-23 16:23:14
|
>>> But this must not be done directly, since providers could be chained to >>> implement things (say trace provider >> >> we discussed it and decided it's bad idea >> > You can decide it for Firebird, but you can't decide it for user. Let > user create *plugins*. I believe, Alex told there about "trace provider" == "bad idea" >>> , log/replay provider >> >> which must log only external calls >> > Code from external engines *is* external calls. May not make sense for a > replay plugin, but it must pass in the yvalve too. Here is an principal point. If external code creates new attachment it is certainly must go thru YValve. But if external code used current attachment - why it *must* go thru YValve ? >> I think that for current attachment (and transaction) external engines >> must directly use appropriate engine interfaces. >> Same for transactions created internally. >> > No, please. Let create good and unified thing, not a lot of specific > thing because we don't want to think. Sorry, but this is just a few worlds. I see no good technical reasons behind it. >>> I propose IProviderManagement interface. The yvalve will creates an >>> instance of IProviderManager and will pass it to the factory that >>> creates a provider. How it could be done ? How YValve knows about *provider's* factories ? ... >> Adriano, are you serious that all described here is simpler than proxy >> objects in engine? :-) >> > I'm *sure* it is. I showed you ~15 lines of code, against > addRefs/releases around by Firebird and all-over-the-world users code. And zero lines of implementation of IProviderManagement interface :) > And, BTW, it will not crash when the engine is unloaded, like I said in > the another message. Why do you think engine could be unloaded if not all references are released ? Regards, Vlad |
From: Adriano d. S. F. <adr...@gm...> - 2011-03-23 16:56:43
|
On 23-03-2011 13:23, Vlad Khorsun wrote: >>>> But this must not be done directly, since providers could be chained to >>>> implement things (say trace provider >>> >>> we discussed it and decided it's bad idea >>> >> You can decide it for Firebird, but you can't decide it for user. Let >> user create *plugins*. > > I believe, Alex told there about "trace provider" == "bad idea" > I said again, he or us can't decide it's bad idea for *user*. It's perfect technically valid idea. It solves the problem of trace only in the server, just for a example. >>>> , log/replay provider >>> >>> which must log only external calls >>> >> Code from external engines *is* external calls. May not make sense for a >> replay plugin, but it must pass in the yvalve too. > > Here is an principal point. If external code creates new attachment it is > certainly must go thru YValve. But if external code used current attachment - > why it *must* go thru YValve ? > One good reason is that yvalve is who makes legacy handles, and the external code *must* be accessible by *current* Firebird API too. >>>> I propose IProviderManagement interface. The yvalve will creates an >>>> instance of IProviderManager and will pass it to the factory that >>>> creates a provider. > > How it could be done ? How YValve knows about *provider's* factories ? > It's yvalve who instantiates plugins. > ... >>> Adriano, are you serious that all described here is simpler than proxy >>> objects in engine? :-) >>> >> I'm *sure* it is. I showed you ~15 lines of code, against >> addRefs/releases around by Firebird and all-over-the-world users code. > > And zero lines of implementation of IProviderManagement interface :) > Well, if I write code you say to not write code but explain ideas before. If I explain ideas you complain about no code... >> And, BTW, it will not crash when the engine is unloaded, like I said in >> the another message. > > Why do you think engine could be unloaded if not all references are released ? > Ah, another set of refcounting to prevent it to unload when only proxies exists... Adriano |
From: Vlad K. <hv...@us...> - 2011-03-23 18:10:18
|
> On 23-03-2011 13:23, Vlad Khorsun wrote: >>>>> But this must not be done directly, since providers could be chained to >>>>> implement things (say trace provider >>>> >>>> we discussed it and decided it's bad idea >>>> >>> You can decide it for Firebird, but you can't decide it for user. Let >>> user create *plugins*. >> >> I believe, Alex told there about "trace provider" == "bad idea" >> > I said again, he or us can't decide it's bad idea for *user*. It's > perfect technically valid idea. It solves the problem of trace only in > the server, just for a example. Then tell *explicitly* that you talk about custom user's API-tracing provider. It is very hard to guess what do you mean here or there >>> Code from external engines *is* external calls. May not make sense for a >>> replay plugin, but it must pass in the yvalve too. >> >> Here is an principal point. If external code creates new attachment it is >> certainly must go thru YValve. But if external code used current attachment - >> why it *must* go thru YValve ? >> > > One good reason is that yvalve is who makes legacy handles, and the > external code *must* be accessible by *current* Firebird API too. Again, you could tell it few days earlyer and save a bit of our and you own time. >>>>> I propose IProviderManagement interface. The yvalve will creates an >>>>> instance of IProviderManager and will pass it to the factory that >>>>> creates a provider. >> >> How it could be done ? How YValve knows about *provider's* factories ? >> > It's yvalve who instantiates plugins. Really ? I thought it is PluginManger, who instantiates plugins. And far not every plugin kind needs IProviderManagement (IYvalveNotify sounds much better for me). >>>> Adriano, are you serious that all described here is simpler than proxy >>>> objects in engine? :-) >>>> >>> I'm *sure* it is. I showed you ~15 lines of code, against >>> addRefs/releases around by Firebird and all-over-the-world users code. >> >> And zero lines of implementation of IProviderManagement interface :) >> > Well, if I write code you say to not write code but explain ideas > before. If I explain ideas you complain about no code... Write code to explain idea is not the same as write code to commit into SVN. And i have no idea about how do you going to implement IProviderManagement. >>> And, BTW, it will not crash when the engine is unloaded, like I said in >>> the another message. >> >> Why do you think engine could be unloaded if not all references are released ? >> > Ah, another set of refcounting to prevent it to unload when only proxies > exists... Why not ? This is another useful example of using refcounting ;) Regards, Vlad |
From: Dmitry Y. <fir...@ya...> - 2011-03-24 06:57:00
|
23.03.2011, 21:10, "Vlad Khorsun" <hv...@us...>: >> How it could be done ? How YValve knows about *provider's* factories ? >> It's yvalve who instantiates plugins. > > Really ? I thought it is PluginManger, who instantiates plugins. I recall an agreement here that PluginManager should be a part of the y-valve, not the engine. Perhaps it's already linked this way, I haven't checked. So I believe Adriano is talking about the y-valve as a library, not as just why.cpp. Dmitry |
From: Vlad K. <hv...@us...> - 2011-03-24 08:33:44
|
>>> How it could be done ? How YValve knows about *provider's* factories ? >>> It's yvalve who instantiates plugins. >> >> Really ? I thought it is PluginManger, who instantiates plugins. > > I recall an agreement here that PluginManager should be a part of the y-valve, not the engine. Perhaps it's already linked this > way, I haven't checked. So I believe Adriano is talking about the y-valve as a library, not as just why.cpp. YValve asks PluginManager to instantiate Providers. But plugns is much more wide than just Providers. And PluginManager is responsible to instantiate all kinds of plugins. And far not all of plugins need callbacks into YValve. Regards, Vlad |
From: Alex P. <pes...@ma...> - 2011-03-24 10:49:06
|
On 03/24/11 11:33, Vlad Khorsun wrote: >>>> How it could be done ? How YValve knows about *provider's* factories ? >>>> It's yvalve who instantiates plugins. >>> Really ? I thought it is PluginManger, who instantiates plugins. >> I recall an agreement here that PluginManager should be a part of the y-valve, not the engine. Perhaps it's already linked this >> way, I haven't checked. So I believe Adriano is talking about the y-valve as a library, not as just why.cpp. > YValve asks PluginManager to instantiate Providers. But plugns is much more wide than just > Providers. And PluginManager is responsible to instantiate all kinds of plugins. And far not all of > plugins need callbacks into YValve. Guys! Looks like currently we call 2 different things with same name yvalve - it's provider's dispatcher (yValve in original understanding) and fbclient library. Suppose this is partially due to badly selected by me name for a directory - src/yvalve. Currently in this directory all external entrypoints if our API are collected, though central part of this is yvalve itself. PluginManager is also a part of that library. And certainly, it's relatively simple to add some additional call from why.cpp to PluginManager. But not any thing, which may be easy done, should be done. Adding additional, absolutely unrelated with overall plugins schema functionality, due to desire to make additional channel for single type of plugins is wrong solution. |
From: Vlad K. <hv...@us...> - 2011-03-24 11:01:22
|
> PluginManager is also a part of that library. And certainly, it's > relatively simple to add some additional call from why.cpp to > PluginManager. But not any thing, which may be easy done, should be > done. Adding additional, absolutely unrelated with overall plugins > schema functionality, due to desire to make additional channel for > single type of plugins is wrong solution. And this is exactly what i said above :) Regards, Vlad |
From: Alex P. <pes...@ma...> - 2011-03-24 11:08:28
|
On 03/24/11 14:01, Vlad Khorsun wrote: >> PluginManager is also a part of that library. And certainly, it's >> relatively simple to add some additional call from why.cpp to >> PluginManager. But not any thing, which may be easy done, should be >> done. Adding additional, absolutely unrelated with overall plugins >> schema functionality, due to desire to make additional channel for >> single type of plugins is wrong solution. > And this is exactly what i said above :) > yes, certainly I only wanted to make sure that main idea is not lost in the heap of various objects same called :) |
From: Adriano d. S. F. <adr...@gm...> - 2011-03-24 13:46:03
|
On 24-03-2011 05:33, Vlad Khorsun wrote: >>>> How it could be done ? How YValve knows about *provider's* factories ? >>>> It's yvalve who instantiates plugins. >>> >>> Really ? I thought it is PluginManger, who instantiates plugins. >> >> I recall an agreement here that PluginManager should be a part of the y-valve, not the engine. Perhaps it's already linked this >> way, I haven't checked. So I believe Adriano is talking about the y-valve as a library, not as just why.cpp. > > YValve asks PluginManager to instantiate Providers. But plugns is much more wide than just > Providers. And PluginManager is responsible to instantiate all kinds of plugins. And far not all of > plugins need callbacks into YValve. > This is because plugins creation is currently using fixed factories, while is much better to have specific factories for specific needs. Adriano |
From: Alex P. <pes...@ma...> - 2011-03-24 14:23:22
|
On 03/24/11 16:45, Adriano dos Santos Fernandes wrote: > On 24-03-2011 05:33, Vlad Khorsun wrote: >>>>> How it could be done ? How YValve knows about *provider's* factories ? >>>>> It's yvalve who instantiates plugins. >>>> Really ? I thought it is PluginManger, who instantiates plugins. >>> I recall an agreement here that PluginManager should be a part of the y-valve, not the engine. Perhaps it's already linked this >>> way, I haven't checked. So I believe Adriano is talking about the y-valve as a library, not as just why.cpp. >> YValve asks PluginManager to instantiate Providers. But plugns is much more wide than just >> Providers. And PluginManager is responsible to instantiate all kinds of plugins. And far not all of >> plugins need callbacks into YValve. >> > This is because plugins creation is currently using fixed factories, > while is much better to have specific factories for specific needs. Currently we have many types of plugins, and all of them work just fine with fixed factories. May be as soon as you want to say - "I want specific factory for some plugin" - it's time to stop and think: are you doing correct things? |
From: Adriano d. S. F. <adr...@gm...> - 2011-03-24 14:37:27
|
On 24-03-2011 11:23, Alex Peshkoff wrote: > On 03/24/11 16:45, Adriano dos Santos Fernandes wrote: >> On 24-03-2011 05:33, Vlad Khorsun wrote: >>>>>> How it could be done ? How YValve knows about *provider's* factories ? >>>>>> It's yvalve who instantiates plugins. >>>>> Really ? I thought it is PluginManger, who instantiates plugins. >>>> I recall an agreement here that PluginManager should be a part of the y-valve, not the engine. Perhaps it's already linked this >>>> way, I haven't checked. So I believe Adriano is talking about the y-valve as a library, not as just why.cpp. >>> YValve asks PluginManager to instantiate Providers. But plugns is much more wide than just >>> Providers. And PluginManager is responsible to instantiate all kinds of plugins. And far not all of >>> plugins need callbacks into YValve. >>> >> This is because plugins creation is currently using fixed factories, >> while is much better to have specific factories for specific needs. > > Currently we have many types of plugins, and all of them work just fine > with fixed factories. May be as soon as you want to say - "I want > specific factory for some plugin" - it's time to stop and think: are you > doing correct things? > Just remember my proposal is not about addRef/release only. Current interface pollutes user code with internal baggage about handles. Are you saying it's correct? Adriano |
From: Alex P. <pes...@ma...> - 2011-03-24 14:45:35
|
On 03/24/11 17:37, Adriano dos Santos Fernandes wrote: > On 24-03-2011 11:23, Alex Peshkoff wrote: >> On 03/24/11 16:45, Adriano dos Santos Fernandes wrote: >>> On 24-03-2011 05:33, Vlad Khorsun wrote: >>>>>>> How it could be done ? How YValve knows about *provider's* factories ? >>>>>>> It's yvalve who instantiates plugins. >>>>>> Really ? I thought it is PluginManger, who instantiates plugins. >>>>> I recall an agreement here that PluginManager should be a part of the y-valve, not the engine. Perhaps it's already linked this >>>>> way, I haven't checked. So I believe Adriano is talking about the y-valve as a library, not as just why.cpp. >>>> YValve asks PluginManager to instantiate Providers. But plugns is much more wide than just >>>> Providers. And PluginManager is responsible to instantiate all kinds of plugins. And far not all of >>>> plugins need callbacks into YValve. >>>> >>> This is because plugins creation is currently using fixed factories, >>> while is much better to have specific factories for specific needs. >> Currently we have many types of plugins, and all of them work just fine >> with fixed factories. May be as soon as you want to say - "I want >> specific factory for some plugin" - it's time to stop and think: are you >> doing correct things? >> > Just remember my proposal is not about addRef/release only. > > Current interface pollutes user code with internal baggage about handles. What handles do you mean? > Are you saying it's correct? > I can't say something cause I do not understand what you say.... |
From: Adriano d. S. F. <adr...@gm...> - 2011-03-24 14:52:08
|
On 24-03-2011 11:45, Alex Peshkoff wrote: > On 03/24/11 17:37, Adriano dos Santos Fernandes wrote: >> On 24-03-2011 11:23, Alex Peshkoff wrote: >>> On 03/24/11 16:45, Adriano dos Santos Fernandes wrote: >>>> On 24-03-2011 05:33, Vlad Khorsun wrote: >>>>>>>> How it could be done ? How YValve knows about *provider's* factories ? >>>>>>>> It's yvalve who instantiates plugins. >>>>>>> Really ? I thought it is PluginManger, who instantiates plugins. >>>>>> I recall an agreement here that PluginManager should be a part of the y-valve, not the engine. Perhaps it's already linked this >>>>>> way, I haven't checked. So I believe Adriano is talking about the y-valve as a library, not as just why.cpp. >>>>> YValve asks PluginManager to instantiate Providers. But plugns is much more wide than just >>>>> Providers. And PluginManager is responsible to instantiate all kinds of plugins. And far not all of >>>>> plugins need callbacks into YValve. >>>>> >>>> This is because plugins creation is currently using fixed factories, >>>> while is much better to have specific factories for specific needs. >>> Currently we have many types of plugins, and all of them work just fine >>> with fixed factories. May be as soon as you want to say - "I want >>> specific factory for some plugin" - it's time to stop and think: are you >>> doing correct things? >>> >> Just remember my proposal is not about addRef/release only. >> >> Current interface pollutes user code with internal baggage about handles. > > What handles do you mean? > The thing about "api" handles that yvalve pass to the providers to them be able to callback yvalve before complete the API (attach/startTransaction) call. Adriano |
From: Alex P. <pes...@ma...> - 2011-03-24 14:59:51
|
On 03/24/11 17:51, Adriano dos Santos Fernandes wrote: > On 24-03-2011 11:45, Alex Peshkoff wrote: >> On 03/24/11 17:37, Adriano dos Santos Fernandes wrote: >>> On 24-03-2011 11:23, Alex Peshkoff wrote: >>>> On 03/24/11 16:45, Adriano dos Santos Fernandes wrote: >>>>> On 24-03-2011 05:33, Vlad Khorsun wrote: >>>>>>>>> How it could be done ? How YValve knows about *provider's* factories ? >>>>>>>>> It's yvalve who instantiates plugins. >>>>>>>> Really ? I thought it is PluginManger, who instantiates plugins. >>>>>>> I recall an agreement here that PluginManager should be a part of the y-valve, not the engine. Perhaps it's already linked this >>>>>>> way, I haven't checked. So I believe Adriano is talking about the y-valve as a library, not as just why.cpp. >>>>>> YValve asks PluginManager to instantiate Providers. But plugns is much more wide than just >>>>>> Providers. And PluginManager is responsible to instantiate all kinds of plugins. And far not all of >>>>>> plugins need callbacks into YValve. >>>>>> >>>>> This is because plugins creation is currently using fixed factories, >>>>> while is much better to have specific factories for specific needs. >>>> Currently we have many types of plugins, and all of them work just fine >>>> with fixed factories. May be as soon as you want to say - "I want >>>> specific factory for some plugin" - it's time to stop and think: are you >>>> doing correct things? >>>> >>> Just remember my proposal is not about addRef/release only. >>> >>> Current interface pollutes user code with internal baggage about handles. >> What handles do you mean? >> > The thing about "api" handles that yvalve pass to the providers to them > be able to callback yvalve before complete the API > (attach/startTransaction) call. May be you have forgotten - one of my proposals is to not pass external handles in attach/startTransaction call. And do not pass them into engine in any way. Cause with new API we have much better way to access current context. |
From: Adriano d. S. F. <adr...@gm...> - 2011-03-24 15:09:31
|
On 24-03-2011 11:59, Alex Peshkoff wrote: > > May be you have forgotten - one of my proposals is to not pass external > handles in attach/startTransaction call. And do not pass them into > engine in any way. Cause with new API we have much better way to access > current context. > If your approach is about don't be able to use current Firebird API with external attachments and transactions (initiated by client or internally), I'm sorry but I can't consider it as usable. Adriano |
From: Alex P. <pes...@ma...> - 2011-03-24 15:53:36
|
On 03/24/11 18:09, Adriano dos Santos Fernandes wrote: > On 24-03-2011 11:59, Alex Peshkoff wrote: >> May be you have forgotten - one of my proposals is to not pass external >> handles in attach/startTransaction call. And do not pass them into >> engine in any way. Cause with new API we have much better way to access >> current context. >> > If your approach is about don't be able to use current Firebird API with > external attachments and transactions (initiated by client or > internally), I'm sorry but I can't consider it as usable. May be you've missed in the thread 'Refcounted API objects': We really need converter from ISC API to new interface. If in external engines we add 2 special handle values - current connection and current transaction, this will solve backward compatibility problem in all places. |
From: Adriano d. S. F. <adr...@gm...> - 2011-03-24 17:28:57
|
On 24-03-2011 12:53, Alex Peshkoff wrote: > On 03/24/11 18:09, Adriano dos Santos Fernandes wrote: >> On 24-03-2011 11:59, Alex Peshkoff wrote: >>> May be you have forgotten - one of my proposals is to not pass external >>> handles in attach/startTransaction call. And do not pass them into >>> engine in any way. Cause with new API we have much better way to access >>> current context. >>> >> If your approach is about don't be able to use current Firebird API with >> external attachments and transactions (initiated by client or >> internally), I'm sorry but I can't consider it as usable. > > May be you've missed in the thread 'Refcounted API objects': > > We really need converter from ISC API to new interface. If in external > engines we > add 2 special handle values - current connection and current > transaction, this will solve backward compatibility problem in all places. > Single handle meaning different things when used in different moments smells like fire to me. Adriano |
From: Alex P. <pes...@ma...> - 2011-03-25 08:27:54
|
On 03/24/11 20:28, Adriano dos Santos Fernandes wrote: > On 24-03-2011 12:53, Alex Peshkoff wrote: >> On 03/24/11 18:09, Adriano dos Santos Fernandes wrote: >>> On 24-03-2011 11:59, Alex Peshkoff wrote: >>>> May be you have forgotten - one of my proposals is to not pass external >>>> handles in attach/startTransaction call. And do not pass them into >>>> engine in any way. Cause with new API we have much better way to access >>>> current context. >>>> >>> If your approach is about don't be able to use current Firebird API with >>> external attachments and transactions (initiated by client or >>> internally), I'm sorry but I can't consider it as usable. >> May be you've missed in the thread 'Refcounted API objects': >> >> We really need converter from ISC API to new interface. If in external >> engines we >> add 2 special handle values - current connection and current >> transaction, this will solve backward compatibility problem in all places. >> > Single handle meaning different things when used in different moments > smells like fire to me. Yes, probably you are right. Even if we take into an account existence of current_user and current_role variables - I agree that this is another usage. But no matter of that fact delivering of original ISC handles into engine is also bad idea. And one of the reasons for it - in many cases there will be nothing to deliver. Server with new interface will work without ISC handles at all, therefore to support old API in external engines you will anyway have to create a kind of pseudo ISC handle. There is absolutely no crime in it - just make it possible to ask API converter: I have IAttacment* (or ITransaction*), please create handle for it. |
From: Adriano d. S. F. <adr...@gm...> - 2011-03-25 15:59:33
|
On 25-03-2011 05:27, Alex Peshkoff wrote: > On 03/24/11 20:28, Adriano dos Santos Fernandes wrote: >> On 24-03-2011 12:53, Alex Peshkoff wrote: >>> On 03/24/11 18:09, Adriano dos Santos Fernandes wrote: >>>> On 24-03-2011 11:59, Alex Peshkoff wrote: >>>>> May be you have forgotten - one of my proposals is to not pass external >>>>> handles in attach/startTransaction call. And do not pass them into >>>>> engine in any way. Cause with new API we have much better way to access >>>>> current context. >>>>> >>>> If your approach is about don't be able to use current Firebird API with >>>> external attachments and transactions (initiated by client or >>>> internally), I'm sorry but I can't consider it as usable. >>> May be you've missed in the thread 'Refcounted API objects': >>> >>> We really need converter from ISC API to new interface. If in external >>> engines we >>> add 2 special handle values - current connection and current >>> transaction, this will solve backward compatibility problem in all places. >>> >> Single handle meaning different things when used in different moments >> smells like fire to me. > > Yes, probably you are right. Even if we take into an account existence > of current_user and current_role variables - I agree that this is > another usage. > > But no matter of that fact delivering of original ISC handles into > engine is also bad idea. And one of the reasons for it - in many cases > there will be nothing to deliver. Server with new interface will work > without ISC handles at all, therefore to support old API in external > engines you will anyway have to create a kind of pseudo ISC handle. > There is absolutely no crime in it - just make it possible to ask API > converter: I have IAttacment* (or ITransaction*), please create handle > for it. > This seems ok. What I had in mind: - Yvalve handles are mapped to Yvalve objects (YAttachment, YTransaction). - We add new API function that translate Yvalve pointer to handle: fb_get_handle(IInterface*, int type) And with your suggestion, then we add a way to make the Yvalve to create a Yvalve object from a provider object, so external code always access provider objects via Yvalve objects. And since external code now receives a Yvalve object, it can gets its legacy handle with fb_get_handle. Adriano |
From: Alex P. <pes...@ma...> - 2011-03-25 16:48:21
|
On 03/25/11 18:59, Adriano dos Santos Fernandes wrote: > On 25-03-2011 05:27, Alex Peshkoff wrote: >> On 03/24/11 20:28, Adriano dos Santos Fernandes wrote: >>> On 24-03-2011 12:53, Alex Peshkoff wrote: >>>> On 03/24/11 18:09, Adriano dos Santos Fernandes wrote: >>>>> On 24-03-2011 11:59, Alex Peshkoff wrote: >>>>>> May be you have forgotten - one of my proposals is to not pass external >>>>>> handles in attach/startTransaction call. And do not pass them into >>>>>> engine in any way. Cause with new API we have much better way to access >>>>>> current context. >>>>>> >>>>> If your approach is about don't be able to use current Firebird API with >>>>> external attachments and transactions (initiated by client or >>>>> internally), I'm sorry but I can't consider it as usable. >>>> May be you've missed in the thread 'Refcounted API objects': >>>> >>>> We really need converter from ISC API to new interface. If in external >>>> engines we >>>> add 2 special handle values - current connection and current >>>> transaction, this will solve backward compatibility problem in all places. >>>> >>> Single handle meaning different things when used in different moments >>> smells like fire to me. >> Yes, probably you are right. Even if we take into an account existence >> of current_user and current_role variables - I agree that this is >> another usage. >> >> But no matter of that fact delivering of original ISC handles into >> engine is also bad idea. And one of the reasons for it - in many cases >> there will be nothing to deliver. Server with new interface will work >> without ISC handles at all, therefore to support old API in external >> engines you will anyway have to create a kind of pseudo ISC handle. >> There is absolutely no crime in it - just make it possible to ask API >> converter: I have IAttacment* (or ITransaction*), please create handle >> for it. >> > This seems ok. > > What I had in mind: > - Yvalve handles are mapped to Yvalve objects (YAttachment, YTransaction). > - We add new API function that translate Yvalve pointer to handle: > fb_get_handle(IInterface*, int type) > > And with your suggestion, then we add a way to make the Yvalve to create > a Yvalve object from a provider object, so external code always access > provider objects via Yvalve objects. And since external code now > receives a Yvalve object, it can gets its legacy handle with fb_get_handle. Now (I talk about SVN state) external code receives ISC handle. But I suggest you to remove this hack from the code and when external engines need to access current attachment/transaction (let me call this pair context later), make them work using engine directly, without yValve. I know your mind that all calls must pass through yValve. But I have not seen any explanation of this requirement. The only reason I remember is 'other types of providers need access to this calls'. But this requirement is rather strange. Let's take a look at SP. It executes some SQL operators, and (I hope) nobody requires this calls to go to yValve. Now imagine that instead direct INSERT INTO SOME_TABLES(SOME_INT) VALUES(123); Now let's rewrite this slightly. EXECUTE STATEMENT 'INSERT INTO SOME_TABLES(SOME_INT) VALUES(123)'; Should it pass through yValve? What's a difference with previous case? And finally let's imagine that some external engine executes same statement in current context. What's the difference between stored procedure, execute statement and external engine (working with current context) that in some cases SQL operator must pass go to yValve, but in others - not? |
From: Adriano d. S. F. <adr...@gm...> - 2011-03-25 17:07:21
|
On 25-03-2011 13:48, Alex Peshkoff wrote: > On 03/25/11 18:59, Adriano dos Santos Fernandes wrote: >> On 25-03-2011 05:27, Alex Peshkoff wrote: >>> On 03/24/11 20:28, Adriano dos Santos Fernandes wrote: >>>> On 24-03-2011 12:53, Alex Peshkoff wrote: >>>>> On 03/24/11 18:09, Adriano dos Santos Fernandes wrote: >>>>>> On 24-03-2011 11:59, Alex Peshkoff wrote: >>>>>>> May be you have forgotten - one of my proposals is to not pass external >>>>>>> handles in attach/startTransaction call. And do not pass them into >>>>>>> engine in any way. Cause with new API we have much better way to access >>>>>>> current context. >>>>>>> >>>>>> If your approach is about don't be able to use current Firebird API with >>>>>> external attachments and transactions (initiated by client or >>>>>> internally), I'm sorry but I can't consider it as usable. >>>>> May be you've missed in the thread 'Refcounted API objects': >>>>> >>>>> We really need converter from ISC API to new interface. If in external >>>>> engines we >>>>> add 2 special handle values - current connection and current >>>>> transaction, this will solve backward compatibility problem in all places. >>>>> >>>> Single handle meaning different things when used in different moments >>>> smells like fire to me. >>> Yes, probably you are right. Even if we take into an account existence >>> of current_user and current_role variables - I agree that this is >>> another usage. >>> >>> But no matter of that fact delivering of original ISC handles into >>> engine is also bad idea. And one of the reasons for it - in many cases >>> there will be nothing to deliver. Server with new interface will work >>> without ISC handles at all, therefore to support old API in external >>> engines you will anyway have to create a kind of pseudo ISC handle. >>> There is absolutely no crime in it - just make it possible to ask API >>> converter: I have IAttacment* (or ITransaction*), please create handle >>> for it. >>> >> This seems ok. >> >> What I had in mind: >> - Yvalve handles are mapped to Yvalve objects (YAttachment, YTransaction). >> - We add new API function that translate Yvalve pointer to handle: >> fb_get_handle(IInterface*, int type) >> >> And with your suggestion, then we add a way to make the Yvalve to create >> a Yvalve object from a provider object, so external code always access >> provider objects via Yvalve objects. And since external code now >> receives a Yvalve object, it can gets its legacy handle with fb_get_handle. > > Now (I talk about SVN state) external code receives ISC handle. But I > suggest you to remove this hack from the code and when external engines > need to access current attachment/transaction (let me call this pair > context later), make them work using engine directly, without yValve. > > I know your mind that all calls must pass through yValve. But I have not > seen any explanation of this requirement. The only reason I remember is > 'other types of providers need access to this calls'. But this > requirement is rather strange. Let's take a look at SP. It executes some > SQL operators, and (I hope) nobody requires this calls to go to yValve. Yvalve defines Firebird API requirements, may check handles (objects too), may do extra things. Don't make sense to move this type of functionality to each provider. Also, let say external code receives an engine IAttachment which was registered in yvalve and now has a handle. Then external code starts to use this handle and start new transaction with legacy API. If this IAttachment is not from yvalve, now yvalve gained another responsibility which is to coordinate engine provider objects. Let yvalve coordinate yvalve objects. In my new version of why.cpp things like CAttachment (C*) classes gone in favor of YAttachment (Y*) objects. Things are much simple and effective, became directly usable without legacy handles, may use the same API (semantics defined in yvalve) for client and external code running on the server. > Now imagine that instead direct > > INSERT INTO SOME_TABLES(SOME_INT) VALUES(123); > > Now let's rewrite this slightly. > > EXECUTE STATEMENT 'INSERT INTO SOME_TABLES(SOME_INT) VALUES(123)'; > > Should it pass through yValve? What's a difference with previous case? > And finally let's imagine that some external engine executes same > statement in current context. What's the difference between stored > procedure, execute statement and external engine (working with current > context) that in some cases SQL operator must pass go to yValve, but in > others - not? > This is pure internal command, has nothing to do with API, so it may execute without yvalve like any other internal command. If it's an external datasource, it must be created by yvalve cause it may go to another provider. Adriano |
From: Dimitry S. <sd...@ib...> - 2011-03-25 17:22:30
|
25.03.2011 18:07, Adriano dos Santos Fernandes wrote: > Also, let say external code receives an engine IAttachment which was > registered in yvalve and now has a handle. Then external code starts to > use this handle and start new transaction with legacy API. Why the code would like to do such stupid things?.. It can start new transaction using received IAttachment. And to accomplish that it doesn't need it's handle. > This is pure internal command, has nothing to do with API, so it may > execute without yvalve like any other internal command. If it's an > external datasource, it must be created by yvalve cause it may go to > another provider. It has sense if the external datasource establish new connection. But for working with current connection to route calls through yvalve is just a lost of time. -- SY, SD. |