On 03/18/13 21:11, Adriano dos Santos Fernandes wrote:
> On 18/03/2013 13:25, Alex Peshkoff wrote:
>> On 03/18/13 17:35, Adriano dos Santos Fernandes wrote:
>>> MyStatusImpl status;    // inline
>>> apiFunction(&status);   // status methods are called only if a error is
>>> throw
>>> status.check()    // inline
>>>
>>> So I have doubts about the provider manner of calling init.
>> Old, well-known conflict between performance and flexibility :)
>> But OK, let's go in this direction if nobody objects. In fact 99, 9999%
>> of that inits will be useless.
>> What's not good is that we add one more 'hidden' difference with old api
>> and in an aspect where it was rather clear.
>> And we have some troubles when we plan to analyze returned IStatus in
>> cases when we pass already existing interface to somebody else. Not
>> typical case, but if we say that in case of no-error status is not
>> changed we will have to add own status variable and probably copy it
>> back to passed to us interface. Telling that on no-error state of
>> IStatus is implementation-defined does not look like good idea.
> Then our implementations should never call a user status get method
> directly, as it may contain garbage (not cleared).

Yes. If we do not perform status cleanup we can't do it, and will have 
to use own instance of status to pass somewhere.
But must notice that

> We may write a delegate that inline initialize cleared and delegates set
> to the caller status.

Can you explain in more details?

>> Therefore great desire to solve first what to do with warnings
>> (how to store them in IStatus better), next change engine code (where
>> that warnings arrive).
> I do not think the problem with warnings is the way it's stored in
> status vector. The main problem is that we can't carry then without a
> IStatus, while we can carry exceptions without it (converting and
> throwing, catching and converting).

More or less same case I've had in client code - there may be internal 
exception (like network error, they are definitely thrown), most of 
exceptions come from server (and they are also thrown in the end of 
response check code), but sometimes we get warning from server, and it 
should not be thrown. In client I use IStatus where warning is to be 
returned, but IMHO any other way (including some new class) may be used 
for it. But before changing something in engine we should better decide 
what to do exactly.

>>> Yes, but have status.check() and try { ... } catch { ... stuff ... }
>>> everywhere is neither elegant.
>> I talk first of all not about elegance, but about having debuggable
>> code. If (for example) boost becomes standard de facto and therefore
>> debiggers are learned to take it into an account, I will certainly agree
>> with using macros in such cases.
> In the case of interface generation with macros, there is possibility to
> preprocess interface headers first and write then to disk. Kinda of IDL
> compiler, but may be done with the preprocessor.
>
> It will have generated code to step into, but not different than if you
> manually write them.

I suppose we have something like
TRY_CATCH_AND_STUFF_MACRO(IStatus*) { /* real code */ }
If yes and we have a way to set debugger breakpoint when it stuffs error 
to IStatus this may be OK.

>>>>> - Checkouts/Checkins:
>>>>>
>>>>> The interaction of checkouts and checkins in the engine is not clear in
>>>>> regard to plugins. AFAIK this was not necessary (external engines first
>>>>> implementation work without some of them introduced later), cause the
>>>>> reentrant locks still work without them. If it's not necessary, why do
>>>>> some of them (checkouts) were introduced?
>>>> Can you be more specific here? What checkouts do you not like?
>>> It's not about I like/dislike. For example, before I implemented
>>> IMetadataBuilder, your recommendation was that user would need to
>>> implement IMessageMetadata getter methods, and with the current API this
>>> is still possible. But you do not implement IMessageMetadata getter
>>> methods with checkouts. How user must know if he can enter in the engine
>>> from this methods or not? If he does, it will happen a checkin without a
>>> checkout.
>>>
>>> This is what I mean. And if it works, why the checkout is necessary on
>>> the more obvious paths?
>> Now I understand a problem. Well, we even do not need new
>> IMessageMetadata - suppose it's possible to find a place where IStatus
>> methods are called w/o checkout. And engine's behavior will be
>> definitely not good. I think that for interfaces like mentioned
>> IMessageMetadata (moreover - IStatus) it's better to prohibit API calls.
>> With check certainly. Not good that this check itself requires
>> resources. May be better ideas? Checkout when we are going to use such
>> methods? For IStatus for example it's almost not needed - it's set()
>> must be called only when receiving exceptions from inner layers. Calls
>> to IMessageMetadata() methods are also well grouped together.
> Seems this prohibitions need to be documented. Also, some (most of)
> external code may not use another thread and call interface methods that
> enters in the engine.

If it will use another thread with another attachment, absolutely no 
problems - that will work.
Problems when same thread tries to enter engine once again w/o checkout.

So we go prohibitions way? If yes they certainly should be
a) documented
b) validated at entrypoints

> But another way to look at it is: I need something. Does it have been
> implemented by someone good? No, then I write it.
>
> But we're doing in 20+ years: I need something. I need to write it.

Less than 13 - ib6 src was published in the end of y2k :-)
If you look at 1.5 code you will see an attempts to use STL classes. But 
that attempt showed that in too many cases use of STL was not OK for us. 
I certainly do not remember all aspects - for example use of allocators 
in STL did not match with what we wanted from pools. But there were 
another problems too, a lot of thm were noticed by Jim when doing vulcan 
port. Therefore we had to use our own classes. May be sometimes a rule 
'I need something. I need to write it.' was used too active where it was 
not needed. Like with smart pointers mentined by you later. But here was 
one more reason - no desire to have a dependency from monster like boost 
(>50Mb in bz2 today).

I suppose that a lot of that issues are gone today. But our classes are 
already written, they work, they do what we want (if not we can easil 
fix them). Why do we need a revolution here?

> And IMHO, this does not always make sense.
>
>>>>> We cannot write C++ code usable internally in Firebird and available to
>>>>> our C++ users.
>>>> And what about Delphi users who need same fucntionality? [Almost sure
>>>> that number of them > number of C++ users. ]
>>> But Firebird is coded in C++, and my point was to externalize our things
>>> that makes usage of API (in C++) easy. But if this code depends on
>>> entire Firebird common library and does not uses standard C++
>>> facilities, no body would want to integrate our code in their projects.
>> API should not be oriented on how internals are coded, including what
>> language is used for it.
> Sure, but if our C++ interface return pointers, why our code should not
> support this pointers with std/boost C++ smart pointers?
>
> If I need to create a small class to better support the API usage (like
> before your new metadata, we needed blr generation and storage), this
> class could not use std containers and would need full FB common library.

But what prevents you from using STL/boost for external API wrappers?

>>>>> We have our strings, we have our exceptions and everyone
>>>>> should adapt to it.
>>>> That wonderful std::string missing even trivial trim() function? No, 
>>>> please!
>>>> Well, I do not remember details why we stopped to use std::exception.
>>>> Something like it was suggested by Jim many years ago.
>> Remembered main problem. For correct use of std::exception RTTI was
>> needed, which seemd to be a problem for some OS (Mac?).
> But what!? If these guys this not fixed this yet, their are not serious
> and we should not care about them. Actually, by download statistics I
> may say they are irrelevant but requires a lot of development resources
> and constrained choices.

As for me I'll be sooner of all very first who wants not to deal with 
apple's products. I already do not hope on something to be fixed - if 
new Darwin release does not break existing API too much that's already 
nice. :(
But some serious sponsors wish that port to be present.

>> With all this new++ technologies the main question comes - what does
>> project win with such code rework? Except possibility of problems on
>> some platforms :( May be I miss some obvious pluses...
>>
> The other way of asking is, what we really win not adopting good OS
> projects and constraining to old tools?

Time for adopting, stability of code base and better portability.

Just one sample - a few years ago a small project libatomic arrived. 
Such a cool thing - no need to deal with them ourself. Well - I've tried 
it, added support to the code in a hope that it will help to port to 
RISC machines and big *nixes. And what? Except HP (who donates to that 
library) nothing works. As the result time spent to adopt libatomic is 
almost wasted. Older tested techologies definitely much better in 
portability.


------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
Firebird-Devel mailing list, web interface at 
https://lists.sourceforge.net/lists/listinfo/firebird-devel

Reply via email to