Go Back   EQEmulator Home > EQEmulator Forums > Archives > Archive::Development > Archive::Development

Archive::Development Archive area for Development's posts that were moved here after an inactivity period of 90 days.

Reply
 
Thread Tools Display Modes
  #1  
Old 11-11-2003, 12:32 PM
Eglin
Hill Giant
 
Join Date: Nov 2003
Posts: 168
Default dbcore.mysql

I'd like to suggest that DBcore.mysql be made protected. Dbcore does not seem to encapsulate the process of walking a recordset
Reply With Quote
  #2  
Old 11-30-2003, 05:48 PM
DeletedUser
Fire Beetle
 
Join Date: Sep 2002
Posts: 0
Default

mysql_store_result downloads the entire recordset into local memory, so there shouldnt be an issue there.

The reason it's private is because of mutex locking issues since DB calls come from multiple threads. Any functions needed should be incorperated into DBCore so that DBCore.mysql isnt exposed to un-threadsafe access.

mysql_store_result would return a null pointer, and cause DBcore::RunQuery to error out with "DB Query Error: No Result" if the connection was broken mid-download.
Reply With Quote
  #3  
Old 11-30-2003, 08:54 PM
Eglin
Hill Giant
 
Join Date: Nov 2003
Posts: 168
Default

Quote:
Originally Posted by Quagmire
mysql_store_result downloads the entire recordset into local memory, so there shouldnt be an issue there.
I must admit, I didn
Reply With Quote
  #4  
Old 12-01-2003, 09:57 AM
DeletedUser
Fire Beetle
 
Join Date: Sep 2002
Posts: 0
Default

[quote=Eglin]I must admit, I didn
Reply With Quote
  #5  
Old 12-01-2003, 10:16 AM
DeletedUser
Fire Beetle
 
Join Date: Sep 2002
Posts: 0
Default

Oh, on the multiple instances part, here's another scenerio.
Say you run 3 queries, coping the information into 3 sets of variables before you want to look and see if any failed, you would have overwritten the information from the first two following your theory, but RunQuery as it is now just copies all relevent data into the variables you provide, freeing you to not have to worry about, even in a single thread situation, the order in which you run queries.

I thought about connection pooling and such, but would honestly would use more resources than you'd gain speed by slowing down the server with multiple connections from each world. It would be perfect if you could create a single pool that all zones on a server drew from, but the interprocess communication is difficult there, unless you redid things so you could host multiple zones in the same process space, which has been thought about before, but always died because we dont want a crash of one zone bringing down 20 zones.

You may want to take a look at the AsyncWork objects, they do pretty much what you're talking about, copy all possible information (result set, all functions that'd be run on the mysql variable, etc) into the class and then allow it to be used later.
Reply With Quote
  #6  
Old 12-01-2003, 04:47 PM
Eglin
Hill Giant
 
Join Date: Nov 2003
Posts: 168
Default

Didn't mean to make too big a deal about this, since I'm a firm believer of the "if it ain't broke, don't fix it" mantra. Thanks for the discourse, though... lots of good issues to think about for future projects.

Quote:
Originally Posted by Quagmire
errbuf and errnum passbacks on RunQuery() hand you the values of the mysql_errno() and mysql_error() commands (with a lil extra added to the string however).
Yeah, of course there is no guarantee that the values returned will relate to your query as opposed to another thread's activities. This is exactly why I suggest that the function(s) be modified to return the mysql_errno directly, rather than just true/false. Probably not likely that the returned errno would differ from the member variable, but possible nonetheless. OTOH, making this change would probably require changes to the client code which is currently expecting true on success and false on failure (assuming they are bothering to check return values) and may therefore not be worth the effort of changnig.

Quote:
RunQuery also already has an automatic reconnect attempt written into it when the connection to the server is lost, so if it returns false, you = screwed.
lol, probably. I just quickly scanned for places where it returned false and noticed that errnum was being set to UINT_MAX and errbuf to "DBcore::RunQuery: No Result" in one instance without really paying attention to what conditional branches were necessary to get there. I was probably just looking at a sanity check.

Quote:
The whole point of the RunQuery() command was to copy all possible information you could need from mysql to variables allocated by the caller (as you see, everything is a pointer for passback there) before unlocking the mutex, and generally make the database querying idiot proof. It passes back the result set, affected rows counter, errno, errstr, last insert id, and handels one attempt to reconnect before giving up all internally. Never had anyone successfully defend a request that more was needed. =P
Yeah, I see that now. My original post was written under the incorrect assumption that mysql_use_rows was being used, rather than mysql_store_rows.

Quote:
Oh, on the multiple instances part, here's another scenerio.
Say you run 3 queries, coping the information into 3 sets of variables before you want to look and see if any failed, you would have overwritten the information from the first two following your theory, but RunQuery as it is now just copies all relevent data into the variables you provide, freeing you to not have to worry about, even in a single thread situation, the order in which you run queries.
DBMSs have large teams of very smart people working on concurrency issues. I seriously doubt that it is going to be possible for any client application to be able to outdo them on this front using their own api. Even substandard (in terms of functionality) DBs like mysql have at least rudimentary support for transactions and rollbacks and row locking and all kinds of other goodies to deal with precisely the type scenario that you mention.

At any rate... stimulating conversation. Lots of good stuff to think about for future projects.
Reply With Quote
  #7  
Old 12-04-2003, 07:08 PM
DeletedUser
Fire Beetle
 
Join Date: Sep 2002
Posts: 0
Default

Quote:
Originally Posted by Eglin
Yeah, of course there is no guarantee that the values returned will relate to your query as opposed to another thread's activities.
Ok, that i just dont understand *at all*. It is 100% guarenteed that it'll be your variable. It is not a member variable that is being returned, you are passing in a memory location for RunQuery to throw the response, it's your responsibility to make sure that the location is valid and wont be overwritten until you're done with it, not DBCore's. Look at the flow a lil bit more, it's not returning a memory location allocated by DBCore where it stored the value, it's asking for a memory location allocated by the caller where you want it to be stored. No probably involed, cant code based on "probably wont happen" (we have people running servers on multi-processor machines, it would happen).
Look and you'll notice that the memory space for errbuf or errnum is allocated in the calling function, then a pointer is passed to RunQuery(), therefore there are no overwrite issues within RunQuery


Quote:
Originally Posted by Eglin
I just quickly scanned for places where it returned false and noticed that errnum was being set to UINT_MAX and errbuf to "DBcore::RunQuery: No Result" in one instance without really paying attention to what conditional branches were necessary to get there. I was probably just looking at a sanity check.
Yep, sanity check. If you pass a result variable to RunQuery and it doesnt return a result (ie, was an insert, update, etc), you'll get that error. errno is set to UINT_MAX on purpose because it's not a mysql error, it's a RunQuery sanity check error.

Quote:
Originally Posted by Eglin
Yeah, I see that now. My original post was written under the incorrect assumption that mysql_use_rows was being used, rather than mysql_store_rows.
Not just talking about the result data, the errno and errbuf memory spaces have to be allocated by the caller, that's how there are no issues about them being overwritten by other threads, and no issues about when they should be freed (within the DBcore code, you still have to worry about that in the calling function of course).

Quote:
Originally Posted by Eglin
DBMSs have large teams of very smart people working on concurrency issues. I seriously doubt that it is going to be possible for any client application to be able to outdo them on this front using their own api. Even substandard (in terms of functionality) DBs like mysql have at least rudimentary support for transactions and rollbacks and row locking and all kinds of other goodies to deal with precisely the type scenario that you mention.
Hehe, completely different topic than i was writing about. =) I was reffering to within our code, not on the server.

Read the code some more. I cant figure out if we're discussing coding theory or the DBCore class, because all of the "errors" you've mentioned in DBCore so far have just been you misunderstanding how it works (or just not caring to look), not a flaw in the code.
Reply With Quote
  #8  
Old 12-04-2003, 07:46 PM
Eglin
Hill Giant
 
Join Date: Nov 2003
Posts: 168
Default

Yup. You are 100% correct. I did not notice (ack, this is becoming too frequent a statement!) that clients provided the memory for errbuff and errnum, assuming instead that it was a member.
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 07:34 PM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3