On Wed, 9 Jun 2010, Rainer Gerhards wrote: > Date: Wed, 9 Jun 2010 10:52:55 +0200 > From: Rainer Gerhards <[email protected]>
>>> Also, strings are not generated before the actions, but while we are >>> processing them. Doing it up front would require even more memory and >>> processing time, because we would need to run over all actions twice >> (once to >>> create the string, once to call the actions, storing all strings >> created). >>> This does not even make sense from a lock contention POV because each >> action >>> has a separate lock, so there can be no lock contention between >> different >>> actions. The question of whether to generate all strings for ONE >> action >>> upfront was the initial question, and I think we have reached some >> consensus >>> on it (meaning that it is at least wroth trying out the performance >> effects >>> and then decide). >> >> I'm not quite clear on the granularity here. >> >> if I have the config >> >> *.* file1 >> *.* file2 >> *.* @ip1 >> *.* @ip2 >> *.* @@ip3 >> *.* @@ip4 >> >> for purposes of the locking, how many separate things are there? > > Sorry, I think should have defined some terms first. > > An *action* is a specific instance of some desired output. The actual > processing carried out is NOT termed "action", even though one could easily > do so. I have to admit I have not defined any term for that. So let's call > this processing. That actual processing is carried out by the output module > (and the really bad thing is that the entry point is named "doAction", which > somewhat implies that the output module is called the action, what is not the > case). > > Each action can use the service of exactly one output module. Each output > module can provide services to many actions. So we have a N:1 relationship > between actions and output modules. > >> depending on how I read your explination, sometimes it sounds like 6 >> (one >> for each line) and sometimes itsounds like 3 (one for file output, one >> for >> UDP send, one for TCP send) > > In the above samples, 3 output modules are involved, where each output module > is used by two actions. We have 6 actions, and so we have 6 action locks. > > So the output module interface does not serialize access to the output > module, but rather to the action instance. All action-specific data is kept > in a separate, per-action data structure and passed into the output module at > the time the doAction call is made. The output module can modify all of this > instance data as if it were running on a single thread. HOWEVER, any global > data items (in short: everything not inside the action instance data) is > *not* synchronized by the rsyslog core. The output module must take care > itself of synchronization if it desires to have concurrent access to such > data items. All current output modules do NOT access global data other than > for config parsing (which is serial and single-threaded by nature). > > I hope this clarifies. If not, please keep asking. It is important to get > this right, and maybe I finally end up expressing me precise enough ;) this clarifies a lot, but not everything if we can handle the following *.* file1 *.* file2 with having two worker threads running, one working on file1 and one working on file2 (with each having per-thred variables for everything except the global data and the actual filedescripter being written to). why couldn't we handle the case *.* file1 with two threads working on different messages. (if there was a lock around the actual write to file1)? I'm not understanding the difference between the two cases. I understnad that you have a lock to prevent this, but I don't understand what the lock is protecting. David Lang _______________________________________________ rsyslog mailing list http://lists.adiscon.net/mailman/listinfo/rsyslog http://www.rsyslog.com

