[AOLSERVER] nsv
hi! My question is about nsv interface is there a way to get for example first key and value (that is not by key, but position) TIA Remigiusz -- ---/\-- Remigiusz Sokolowski e-mail: [EMAIL PROTECTED]/ \ -/\-
Re: [AOLSERVER] nsv
No. NSV uses hashes so there really is no concept of a "first" key/value pair. /s. > hi! > My question is about nsv interface > is there a way to get for example first key and value (that is not by > key, but position) > TIA > Remigiusz > -- > > ---/\- - > Remigiusz Sokolowski e-mail: [EMAIL PROTECTED]/ \ > -/\--- -- > >
[AOLSERVER] nsv docs
can someone point me to the new location of the nsv docs? thanks, scott laplante
[AOLSERVER] nsv performance
Hi, I hope someone with a better understanding of the inner workings of nsv can answer this for me: I would like to store application settings in the database, then on startup, load these into memory and be able to update those on the fly afterwards. nsv sets come into mind to do that. Would that be a good idea? This will be mostly reading values, they would be rarely updated. Think something in the order of 20 reads from different keys in the same set per page. During a read, are sets locked for other readers, or only for writers? Could they also be used for storing session data? I was thinking one "sessions" set, with session key as key and a tcl list-oflists as values. In another set I would keep track of which sessions exist and should be checked for expiration. This will mean there will be as many reads as writes, "check out" the session at the beginning of a page, modify the lists, check back into the set at the end of the page. Or is there a better way to do sessions? Cheers, Bas.
Re: [AOLSERVER] nsv docs
nsv docs are at http://www.aolserver.com/docs/devel/tcl/nsv-commands.adp -Original Message- From: AOLserver Discussion [mailto:[EMAIL PROTECTED]]On Behalf Of Scott Laplante Sent: Thursday, November 15, 2001 12:32 PM To: [EMAIL PROTECTED] Subject: [AOLSERVER] nsv docs can someone point me to the new location of the nsv docs? thanks, scott laplante
Re: [AOLSERVER] nsv performance
Bas, fancy meeting you *here* ;-) I've recently nabbed the session management code from OpenACS and got this working on vanilla AOLserver. This uses nsv's to store stuff in memory and periodically writes back to the database. I can send you what I've got if you like. Take a look at the OpenACS docs on their security design: http://openacs.org/doc/openacs-4/security-design.html Tim > -Original Message- > From: AOLserver Discussion [mailto:[EMAIL PROTECTED]]On Behalf > Of Bas Scheffers > Sent: Tuesday, February 18, 2003 9:59 AM > To: [EMAIL PROTECTED] > Subject: [AOLSERVER] nsv performance > > > Hi, > > I hope someone with a better understanding of the inner workings of nsv > can answer this for me: > > I would like to store application settings in the database, then on > startup, load these into memory and be able to update those on the fly > afterwards. nsv sets come into mind to do that. Would that be a good idea? > This will be mostly reading values, they would be rarely updated. Think > something in the order of 20 reads from different keys in the same set per > page. > > During a read, are sets locked for other readers, or only for writers? > > Could they also be used for storing session data? I was thinking one > "sessions" set, with session key as key and a tcl list-oflists as values. > In another set I would keep track of which sessions exist and should be > checked for expiration. This will mean there will be as many reads as > writes, "check out" the session at the beginning of a page, modify the > lists, check back into the set at the end of the page. Or is there a > better way to do sessions? > > Cheers, > Bas. >
[AOLSERVER] nsv API in C ?
Folks, has anyone implemented a C NSV API, or does anyone plan to? Clearly the right thing to do would be to move the functinality in aolserver/nsd/tclvar.c into C API functions, and re-implement the nsv Tcl commands to that C API. But since I needed to use some nsv commands from C, and I was in a hurry, I just kludged up my own C NSV functions using Ns_TclEval, like the example below. So has anybody done this in a less kludgy fashion? Also, any guesses as to what sort of performance hit I'm taking by using Ns_TclEval? static int BB_NsvSet(const char *nsvString, const char *keyString, const char *valueString) { static const char func_name[] = "BB_NsvSet"; Ns_DString dsScript; Ns_DString dsResult; int rc; Ns_DStringInit(&dsScript); Ns_DStringInit(&dsResult); /* * The key and value may each have embedded whitespace, as we are * surronding them with double quotes. But we asumme that the nsv * array name will always be one word. */ Ns_DStringVarAppend(&dsScript, "nsv_set ", nsvString, " ", "\"", keyString, "\"", " ", "\"", valueString, "\"", NULL); rc = Ns_TclEval(&dsResult, NULL, dsScript.string); Ns_DStringFree(&dsScript); Ns_DStringFree(&dsResult); return rc; } -- Andrew Piskorski <[EMAIL PROTECTED]> http://www.piskorski.com
[AOLSERVER] nsv vs. ns_cache vs. ns_share
All, I've got an issue with lock contention using nsvs. Our site has a huge hash table of categories that is loaded once when the server starts, and is modified rarely. It is used frequently throughout the site. Currently we're keeping it in an nsv. The problem is, under heavy load, we get into serious lock contention problems reading from it. 99.99% of the time we are just reading, so ideally I'd like to use something akin to a read/write lock, however, the overhead of an actual rwlock will probably only make matters worse. The table is far too large (~50,000 entries)to just load up every time an interp is initialized. I contemplated using ns_share, but after reading the source, decided it would be even worse. (Much worse). Any ideas for me? Is there any way to create a shared read-only datastructure that doesn't use thread interlocking? Do I need to code my datastructure up in C? Thanks, Sean
[AOLSERVER] nsv performance characteristics - nscache instead?
I am using nsv arrays to hold session data across multiple page accesses, and to hold some relatively static widely-shared database data to avoid unnecessary database reads. Probably at any point in time there will be several hundred plus nsv arrays with a few K bytes in each, but I haven't spent time to build a good model, and that may be a low estimate. I'm running under RedHat Linux 7.2 with 512MB RAM, OpenACS and PostgreSQL. My site will deliver interactive training, involving light to modest traffic with an average of ten or fifteen database reads / writes per page delivered. I want to be sure the system delivers rapid response time to our users. Without having read the nsv code, but guessing how it's probably implemented, I am making some assumptions about performance characteristics. Am I far off base? - Since Linux provides a virtual memory facility, there is no practical issue of running out of memory and crashing as long as I apply some restraint in using nsvs. - But of course, if the system has to do a lot of page swapping, performance will degrade. - If I want to purge stale or unaccessed data in the nsv arrays, I have to do it myself. I have read how to set the nsvbuckets parameter and monitor lock contention with mutex monitoring, and can experiment with that. Is there any way to monitor the amount of space consumed by nsv arrays at any point in time? What should I do to monitor the performance impact of my nsv use (other than the mutex monitoring), and perhaps to trigger more aggressive purges - or rewrites :( - when needed? I realize that nscache provides similar facilities. There is so much else on my plate, and my facility with Linux internals is so limited, I hesitate to go down the path of installing it. Would it provide a major improvement, so that I should invest that time and energy? Thanks! Dave
Re: [AOLSERVER] nsv API in C ?
Could you not call NsTclVSetCmd() yourself? Look in nsd/tclvar.c ... -- Dossy On 2002.05.03, Andrew Piskorski <[EMAIL PROTECTED]> wrote: > Folks, has anyone implemented a C NSV API, or does anyone plan to? > > Clearly the right thing to do would be to move the functinality in > aolserver/nsd/tclvar.c into C API functions, and re-implement the nsv > Tcl commands to that C API. > > But since I needed to use some nsv commands from C, and I was in a > hurry, I just kludged up my own C NSV functions using Ns_TclEval, like > the example below. > > So has anybody done this in a less kludgy fashion? Also, any guesses > as to what sort of performance hit I'm taking by using Ns_TclEval? > > > static int > BB_NsvSet(const char *nsvString, > const char *keyString, const char *valueString) > { >static const char func_name[] = "BB_NsvSet"; >Ns_DString dsScript; >Ns_DString dsResult; >int rc; > >Ns_DStringInit(&dsScript); >Ns_DStringInit(&dsResult); > >/* > * The key and value may each have embedded whitespace, as we are > * surronding them with double quotes. But we asumme that the nsv > * array name will always be one word. > */ > >Ns_DStringVarAppend(&dsScript, "nsv_set ", nsvString, " ", >"\"", keyString, "\"", " ", >"\"", valueString, "\"", NULL); > >rc = Ns_TclEval(&dsResult, NULL, dsScript.string); > >Ns_DStringFree(&dsScript); >Ns_DStringFree(&dsResult); > >return rc; > } > > -- > Andrew Piskorski <[EMAIL PROTECTED]> > http://www.piskorski.com -- Dossy Shiobara mail: [EMAIL PROTECTED] Panoptic Computer Network web: http://www.panoptic.com/ "He realized the fastest way to change is to laugh at your own folly -- then you can let go and quickly move on." (p. 70)
Re: [AOLSERVER] nsv API in C ?
You should use the following: static int BB_NsvSet(const char *nsvString, const char *keyString, const char *valueString) { Tcl_Obj *o[4]; o[0]=Tcl_NewStringObj("nsv_set",7); o[1]=Tcl_NewStringObj(nsvString,-1); o[2]=Tcl_NewStringObj(keyString,-1); o[3]=Tcl_NewStringObj(valueString,-1); Tcl_IncrRefCount(o[0]); Tcl_IncrRefCount(o[1]); Tcl_IncrRefCount(o[2]); Tcl_IncrRefCount(o[3]); Tcl_EvalObjv(interp,4,&o[0],0); Tcl_DecrRefCount(o[0]); Tcl_DecrRefCount(o[1]); Tcl_DecrRefCount(o[2]); Tcl_DecrRefCount(o[3]); } This one uses Tcl objects (it won't work with 7.6 Tcl :), the main advantage is that it will set strings with quotes - like BB_NsvSet("a","b","\""); Your code will fail with this one. Don't know about speed performance though. Andrew Piskorski wrote: > Folks, has anyone implemented a C NSV API, or does anyone plan to? > > Clearly the right thing to do would be to move the functinality in > aolserver/nsd/tclvar.c into C API functions, and re-implement the nsv > Tcl commands to that C API. > > But since I needed to use some nsv commands from C, and I was in a > hurry, I just kludged up my own C NSV functions using Ns_TclEval, like > the example below. > > So has anybody done this in a less kludgy fashion? Also, any guesses > as to what sort of performance hit I'm taking by using Ns_TclEval? > > > static int > BB_NsvSet(const char *nsvString, > const char *keyString, const char *valueString) > { >static const char func_name[] = "BB_NsvSet"; >Ns_DString dsScript; >Ns_DString dsResult; >int rc; > >Ns_DStringInit(&dsScript); >Ns_DStringInit(&dsResult); > >/* > * The key and value may each have embedded whitespace, as we are > * surronding them with double quotes. But we asumme that the nsv > * array name will always be one word. > */ > >Ns_DStringVarAppend(&dsScript, "nsv_set ", nsvString, " ", >"\"", keyString, "\"", " ", >"\"", valueString, "\"", NULL); > >rc = Ns_TclEval(&dsResult, NULL, dsScript.string); > >Ns_DStringFree(&dsScript); >Ns_DStringFree(&dsResult); > >return rc; > } > > -- > Andrew Piskorski <[EMAIL PROTECTED]> > http://www.piskorski.com > > > -- WK "UTF-8 has a certain purity in that it equally annoys every nation, and is nobody's default encoding." -- Andy Robinson
Re: [AOLSERVER] nsv API in C ?
On Sat, May 04, 2002 at 01:31:42AM -0400, Dossy wrote: > Could you not call NsTclVSetCmd() yourself? Look in > nsd/tclvar.c ... Hm. NsTclVSetCmd() does stuff to or with the Tcl interpretor, and I don't HAVE any convenient local "interp" pointer in my C function to pass is. Should I be passing the interp pointer into my C function, so I can use it for things like NsTclVSetCmd()? But then, I should check the return value in the Tcl interp or something to figure out what actually happened? I dunno. (Clearly though, that wouldn't be any worse than the non-existant error checking I have in my BB_NsvSet() using Ns_TclEval() right now.) Basically, I don't understand why NsTclVSetCmd() is implemented the way it is, rather than as a pair of two functions: 1. NsVSetCmd() function for use by C which does not use any Tcl interp at all. 2. NsTclVSetCmd() which implements the nsv_set Tcl command and calls NsVSetCmd() to do the actual work. -- Andrew Piskorski <[EMAIL PROTECTED]> http://www.piskorski.com
Re: [AOLSERVER] nsv API in C ?
On 2002.05.04, Andrew Piskorski <[EMAIL PROTECTED]> wrote: > On Sat, May 04, 2002 at 01:31:42AM -0400, Dossy wrote: > > Could you not call NsTclVSetCmd() yourself? Look in > > nsd/tclvar.c ... > > Hm. NsTclVSetCmd() does stuff to or with the Tcl interpretor, and I > don't HAVE any convenient local "interp" pointer in my C function to > pass is. Should I be passing the interp pointer into my C function, > so I can use it for things like NsTclVSetCmd()? Yes. That's what I would do. > But then, I should check the return value in the Tcl interp or > something to figure out what actually happened? I dunno. (Clearly > though, that wouldn't be any worse than the non-existant error > checking I have in my BB_NsvSet() using Ns_TclEval() right now.) If you're not passing the interp to Ns_TclEval to tell it in which interpreter to perform the TclEval ... then don't you wonder which interp it's using? > Basically, I don't understand why NsTclVSetCmd() is implemented the > way it is, rather than as a pair of two functions: > 1. NsVSetCmd() function for use by C which does not use any Tcl > interp at all. > 2. NsTclVSetCmd() which implements the nsv_set Tcl command and calls > NsVSetCmd() to do the actual work. You need to grab a lock for the particular interp and its thread. That implies to me that you need to be able to specify the interp. Or, maybe you're right and my understanding of the nsv implementation is wrong. Entirely possible. I do think that the "meat" of the actual nsv C code should be refactored into a NsVSetCmd() or something similar, but if it isn't safe to call directly, then perhaps that's a valid reason not to refactor it out -- to prevent people from calling it wrong. -- Dossy -- Dossy Shiobara mail: [EMAIL PROTECTED] Panoptic Computer Network web: http://www.panoptic.com/ "He realized the fastest way to change is to laugh at your own folly -- then you can let go and quickly move on." (p. 70)
Re: [AOLSERVER] nsv API in C ?
On Sat, May 04, 2002 at 11:06:09AM -0400, Dossy wrote: > On 2002.05.04, Andrew Piskorski <[EMAIL PROTECTED]> wrote: > > On Sat, May 04, 2002 at 01:31:42AM -0400, Dossy wrote: > If you're not passing the interp to Ns_TclEval to tell it in which > interpreter to perform the TclEval ... then don't you wonder which > interp it's using? Um... I admit that never occurred to me. Ah, Ns_TclEval calls Ns_TclAllocateInter, which in this case should be returning the interpretor for my current thread, which is fine. But your suggestion to NsTclVSetCmd() directly definitely sounds like a better idea. > You need to grab a lock for the particular interp and its thread. > That implies to me that you need to be able to specify the interp. > > Or, maybe you're right and my understanding of the nsv implementation > is wrong. Entirely possible. I haven't studied the tclvar.c much, but why would nsv locks have anything to do with threads at all? The nsv data structures are server-wide, after all, so I don't THINK there's anything per-thread or per-interp about them at all. It isn't obvious to me how those data structures are really set up though. There're the "Bucket" and "Array" struct typedefs, and then the "static Bucket *buckets" array, but I'm not entirely clear on how they all actually interact. > I do think that the "meat" of the actual nsv C code should be > refactored into a NsVSetCmd() or something similar, but if it isn't > safe to call directly, then perhaps that's a valid reason not to > refactor it out -- to prevent people from calling it wrong. I don't THINK there's any reason it wouldn't be safe to call the re-factored C functins directly. And I'd be willing to do the refactoring - not right now but sometime. So if somebody who really understands this can give some guidance on the locking and design questions Dossy raised, I'd appreciate it. -- Andrew Piskorski <[EMAIL PROTECTED]> http://www.piskorski.com
Re: [AOLSERVER] nsv API in C ?
On 2002.05.04, Andrew Piskorski <[EMAIL PROTECTED]> wrote: > I haven't studied the tclvar.c much, but why would nsv locks have > anything to do with threads at all? The nsv data structures are > server-wide, after all, so I don't THINK there's anything per-thread > or per-interp about them at all. When you go to update an nsv, you need exclusive access to the nsv you're updating. So, you need an exlusive lock that only grants your interp in your thread to update it, preventing other threads and other interps from doing so. Makes sense to me ... I could be wrong. -- Dossy -- Dossy Shiobara mail: [EMAIL PROTECTED] Panoptic Computer Network web: http://www.panoptic.com/ "He realized the fastest way to change is to laugh at your own folly -- then you can let go and quickly move on." (p. 70)
Re: [AOLSERVER] nsv vs. ns_cache vs. ns_share
If there is any possibility, try breaking up you array into several arrays. Then you can use more than one nsv bucket. Or how do tcl arrays work? If they use a hashtable as well, then you can use a global array, can't you? global copy_array array set copy_array [nsv_array get main_array] --Tom Jackson Sean Owen wrote: > > All, > > I've got an issue with lock contention using nsvs. > > Our site has a huge hash table of categories that is loaded once when the > server starts, and is modified rarely. It is used frequently throughout the > site. Currently we're keeping it in an nsv. > > The problem is, under heavy load, we get into serious lock contention > problems reading from it. 99.99% of the time we are just reading, so > ideally I'd like to use something akin to a read/write lock, however, the > overhead of an actual rwlock will probably only make matters worse. > > The table is far too large (~50,000 entries)to just load up every time an > interp is initialized. > > I contemplated using ns_share, but after reading the source, decided it > would be even worse. (Much worse). > > Any ideas for me? Is there any way to create a shared read-only > datastructure that doesn't use thread interlocking? Do I need to code my > datastructure up in C? > > Thanks, > Sean
Re: [AOLSERVER] nsv vs. ns_cache vs. ns_share
Sean Owen wrote: > All, > > I've got an issue with lock contention using nsvs. > > Our site has a huge hash table of categories that is loaded once when the > server starts, and is modified rarely. It is used frequently throughout the > site. Currently we're keeping it in an nsv. > > The problem is, under heavy load, we get into serious lock contention > problems reading from it. 99.99% of the time we are just reading, so > ideally I'd like to use something akin to a read/write lock, however, the > overhead of an actual rwlock will probably only make matters worse. > > The table is far too large (~50,000 entries)to just load up every time an > interp is initialized. > > I contemplated using ns_share, but after reading the source, decided it > would be even worse. (Much worse). > > Any ideas for me? Is there any way to create a shared read-only > datastructure that doesn't use thread interlocking? Do I need to code my > datastructure up in C? > > Thanks, > Sean > > i'm not sure how you would get something a whole lot more efficient than nsv's if the infrequent updates can happen at any time. you still need to do a mutex of some sort. i would make sure the mutexes are actually the bottleneck. tom jackson's idea of splitting up the nsv's into a set of nsv's seems like a good idea to me id' try that first it is easy for you to do.. -- Mike Hoegeman Email: [EMAIL PROTECTED] Phone: 805-279-7306
Re: [AOLSERVER] nsv vs. ns_cache vs. ns_share
+-- On Sep 10, Sean Owen said: > The problem is, under heavy load, we get into serious lock contention > problems reading from it. Are you speculating or have you looked at the mutex statistics? > 99.99% of the time we are just reading, so > ideally I'd like to use something akin to a read/write lock, however, the > overhead of an actual rwlock will probably only make matters worse. > > The table is far too large (~50,000 entries)to just load up every time an > interp is initialized. We need to know more about your usage pattern. Each NSV is a hash table. Are you using a lot of NSVs or one NSV with 50,000 keys? Do you access the NSV once per request, or many times per request? > Any ideas for me? Is there any way to create a shared read-only > datastructure that doesn't use thread interlocking? Do I need to code my > datastructure up in C? Yes, you'd need to do it in C. I'd do something like this, but I haven't tested this code: /* * An "atomicdata" is a global hash table. One atomicdata in the system * is considered "active". * * Each atomicdata has a reference count. When an atomicdata's reference * count is zero and it is not the active atomicdata, all resources * consumed by that atomicdata are freed. * * The command "dqd_atomicdata set {k1 v1 k2 v2 ...}" creates a new * atomicdata with reference count zero. It fills it with the key/value * pairs k1/v1, k2/v2, etc. Then it atomically makes that new atomicdata * be the active atomicdata. If there was already an active atomicdata, * then the command BLOCKS until the old atomicdata's reference count * is zero and then frees the old atomicdata's resources. Any other * thread that has a reference to the old atomicdata continues to access * the old atomicdata (blocking this thread) until it releases its * reference. * * The command "dqd_atomicdata get k" causes the current thread to * check whether it has a reference to an atomicdata. If it does not, * then it acquires a reference to the active atomicdata and increments * the active atomicdata's reference count. Once the thread is certain * that it has a reference to some atomicdata, it looks up "k" in the * atomicdata. If "k" is found, then the command returns the value * associated with "k". Otherwise, it returns an error. In either case, * the reference to the atomicdata is saved for use by future calls to * "dqd_atomicdata get" in the same thread. * * The command "dqd_atomicdata release" checks whether the current * thread has a reference to some atomicdata. If it does not, then the * command simply returns "0". If the thread does have a reference to an * atomicdata, then the command decrements the atomicdata's reference * count and forgets the reference. * * Each connection thread automatically performs the equivalent of * "dqd_atomicdata release" after completing each HTTP request. You * should use "dqd_atomicdata release" in threads that you create and in * scheduled procs. * * A thread must lock a mutex momentarily to acquire a reference to the * active atomicdata, and to release its reference, and to replace the * active atomicdata. No locking is required when a thread already has a * reference to an atomicdata. */ #ifndef USE_TCL8X #define USE_TCL8X #endif #include "ns.h" int Ns_ModuleVersion = 1; typedef struct AtomicData { Tcl_HashTable table; int refCnt; } AtomicData; /* * Threads will access this to get the current table. When we need * to modify the table, we'll construct a new one from scratch and * atomically swap them out. */ static AtomicData *global_ad; /* These will protect access to global_ad->refCnt. */ static Ns_Mutex ad_lock; static Ns_Cond ad_cond; /* Hold each thread's reference to global_ad. */ static Ns_Tls ad_tls; static AtomicData * acquire(void) { AtomicData *ad = Ns_TlsGet(&ad_tls); if (ad == NULL) { Ns_MutexLock(&ad_lock); ad = global_ad; ad->refCnt++; Ns_MutexUnlock(&ad_lock); Ns_TlsSet(&ad_tls, ad); } return ad; } static int release(void) { AtomicData *ad = Ns_TlsGet(&ad_tls); if (ad == NULL) return 0; Ns_TlsSet(&ad_tls, NULL); Ns_MutexLock(&ad_lock); if (--ad->refCnt == 0) Ns_CondBroadcast(&ad_cond); Ns_MutexUnlock(&ad_lock); return 1; } static void setGlobal(Tcl_HashTable *newTable) { AtomicData *ad = (AtomicData *) ns_malloc(sizeof *ad); AtomicData *old_ad; Tcl_HashEntry *he; Tcl_HashSearch search; ad->table = *newTable; ad->refCnt = 0; Ns_MutexLock(&ad_lock); old_ad = global_ad; global_ad = ad; while (old_ad->refCnt != 0) { Ns_CondWait(&ad_cond, &ad_lock); } Ns_MutexUnlock(&ad_lock); he = Tcl_FirstHashEntry(&old_ad->table, &search); while (he != NULL) { ns_free((void *) Tcl_GetHashValue(he)); he = Tcl_NextHashEntry(&search); } ns_free((void *) old_ad); } static int setCommand(Tcl_Interp *interp,
Re: [AOLSERVER] nsv vs. ns_cache vs. ns_share
Okay, so one time out of ten thousand will be a write to the structure. Is it important that: A) if at time t, a thread determines that slot n should be modified, must all reads from t on find the new, modified value, or would it be okay for other threads to use the old value for some window of time? B) the write be "as quick" as a read, or can a write be a lengthy process? What I wondering is if you couldn't create a structure (in C if need be), that uses NO locking at all, and is only valid for read only access. It's then up to any writers to cooperate with each other, and what a writer does is take out a lock on different table, then completely copy all 50,000 entries to a new table, modify the entry it needs to, and swap the new table for the old, and then release the lock. Modifying the table becomes lengthy, you need to verify on your platform that you can swap a pointer in an atomic operation, readers can get old values for some period of time, but readers never have to lock the table. Jerry Jerry Asher [EMAIL PROTECTED] 1678 Shattuck Avenue Suite 161 Tel: (510) 549-2980 Berkeley, CA 94709 Fax: (877) 311-8688
Re: [AOLSERVER] nsv vs. ns_cache vs. ns_share
+-- On Sep 10, Jerry Asher said: > Modifying the table becomes lengthy, you need to verify on your platform > that you can swap a pointer in an atomic operation, readers can get old > values for some period of time, but readers never have to lock the table. Consider this: reader is accessing table A, uses whole time slice and gets preempted; it has pointers to table A internals in registers/stack writer copies table A to table B, makes table B active writer copies table B to table A, makes table A active reader gets CPU back, is still accessing table A but A's internals have been changed, reader gets SIGSEGV
Re: [AOLSERVER] nsv vs. ns_cache vs. ns_share
At 07:28 PM 9/10/01, you wrote: >+-- On Sep 10, Jerry Asher said: > > Modifying the table becomes lengthy, you need to verify on your platform > > that you can swap a pointer in an atomic operation, readers can get old > > values for some period of time, but readers never have to lock the table. > >Consider this: > > reader is accessing table A, uses whole time slice and gets > preempted; it has pointers to table A internals in registers/stack > > writer copies table A to table B, makes table B active > > writer copies table B to table A, makes table A active > > reader gets CPU back, is still accessing table A but A's internals > have been changed, reader gets SIGSEGV I'm not sure. It's true that the writer shouldn't just free the table -- I guess that readers need to refcount it (and unrefcount it), and I'm not sure how that's done or what that does in terms of overhead. But I would think that if it's a tcl coordinated refcounted table, it wouldn't go away if the reading routine has inc'd it's ref count, the reader is just reading from a table that "newer" readers wouldn't be reading from. There does need to be some algorithm to reclaim storage from refcount 0 tables and to keep track of them. I'm not sure how Tcl does that. Or I might be all wet. Jerry Jerry Asher [EMAIL PROTECTED] 1678 Shattuck Avenue Suite 161 Tel: (510) 549-2980 Berkeley, CA 94709 Fax: (877) 311-8688
Re: [AOLSERVER] nsv vs. ns_cache vs. ns_share
+-- On Sep 10, Jerry Asher said: > I'm not sure. It's true that the writer shouldn't just free the table -- I > guess that readers need to refcount it (and unrefcount it), You cannot, in C, atomically modify a reference count in memory. It might be possible to do so from assembler on some platforms, but a portable implementation must use a lock.
Re: [AOLSERVER] nsv vs. ns_cache vs. ns_share
To answer the various responses I've received: I have verified the lock contention problem by viewing mutex statistics. The offending nsv bucket got 100 times more locks than any other, and under heavy load was busy up to 48% of the time. Not good. I also verified that the hashtable in question was the primary source of the locks. It's a single nsv. It can be (and frequently is) used multiple times per page. The suggestion from various people to split it up is a promising possibility; I'll see if it's feasible for my data structure. The structure is updated rarely enough that it would be acceptable to have to rebuild the entire data structure any time a single element was changed. The C module I had in mind would be called something like ns_const. It would be similar to nsvs, except it would perform no locking; any change would require the datastructure to be rebuilt from scratch. Thanks very much to everyone for the responses. Regards, Sean -Original Message- From: Rob Mayoff [mailto:[EMAIL PROTECTED]] Sent: Monday, September 10, 2001 7:09 PM Subject: Re: nsv vs. ns_cache vs. ns_share +-- On Sep 10, Sean Owen said: > The problem is, under heavy load, we get into serious lock contention > problems reading from it. Are you speculating or have you looked at the mutex statistics? > 99.99% of the time we are just reading, so > ideally I'd like to use something akin to a read/write lock, however, the > overhead of an actual rwlock will probably only make matters worse. > > The table is far too large (~50,000 entries)to just load up every time an > interp is initialized. We need to know more about your usage pattern. Each NSV is a hash table. Are you using a lot of NSVs or one NSV with 50,000 keys? Do you access the NSV once per request, or many times per request? > Any ideas for me? Is there any way to create a shared read-only > datastructure that doesn't use thread interlocking? Do I need to code my > datastructure up in C? Yes, you'd need to do it in C. I'd do something like this, but I haven't tested this code: /* * An "atomicdata" is a global hash table. One atomicdata in the system * is considered "active". * * Each atomicdata has a reference count. When an atomicdata's reference * count is zero and it is not the active atomicdata, all resources * consumed by that atomicdata are freed. * * The command "dqd_atomicdata set {k1 v1 k2 v2 ...}" creates a new * atomicdata with reference count zero. It fills it with the key/value * pairs k1/v1, k2/v2, etc. Then it atomically makes that new atomicdata * be the active atomicdata. If there was already an active atomicdata, * then the command BLOCKS until the old atomicdata's reference count * is zero and then frees the old atomicdata's resources. Any other * thread that has a reference to the old atomicdata continues to access * the old atomicdata (blocking this thread) until it releases its * reference. * * The command "dqd_atomicdata get k" causes the current thread to * check whether it has a reference to an atomicdata. If it does not, * then it acquires a reference to the active atomicdata and increments * the active atomicdata's reference count. Once the thread is certain * that it has a reference to some atomicdata, it looks up "k" in the * atomicdata. If "k" is found, then the command returns the value * associated with "k". Otherwise, it returns an error. In either case, * the reference to the atomicdata is saved for use by future calls to * "dqd_atomicdata get" in the same thread. * * The command "dqd_atomicdata release" checks whether the current * thread has a reference to some atomicdata. If it does not, then the * command simply returns "0". If the thread does have a reference to an * atomicdata, then the command decrements the atomicdata's reference * count and forgets the reference. * * Each connection thread automatically performs the equivalent of * "dqd_atomicdata release" after completing each HTTP request. You * should use "dqd_atomicdata release" in threads that you create and in * scheduled procs. * * A thread must lock a mutex momentarily to acquire a reference to the * active atomicdata, and to release its reference, and to replace the * active atomicdata. No locking is required when a thread already has a * reference to an atomicdata. */ #ifndef USE_TCL8X #define USE_TCL8X #endif #include "ns.h" int Ns_ModuleVersion = 1; typedef struct AtomicData { Tcl_HashTable table; int refCnt; } AtomicData; /* * Threads will access this to get the current table. When we need * to modify the table, we'll construct a new one from scratch and * atomically swap them out. */ static AtomicData *global_ad; /* These will protect access to global_ad->refCnt. */ static Ns_Mutex ad_lock; static Ns_Cond ad_cond; /* Hold each thread's reference to global_ad. */ static Ns_Tls ad_tls; static AtomicData * acquire(void) { AtomicData *ad = Ns_TlsGet(&ad_tls); if (
Re: [AOLSERVER] nsv vs. ns_cache vs. ns_share
This is true, but is atomicity really required? If you don't mind the memory being taken up for a few extra cycles, it seems to me that if you point the API at the new version of the hash table, you can poll the reference count for the old version once a second until it is zero, and then safely free the memory. What's a little busywaiting among friends? -S. -Original Message- From: Rob Mayoff [mailto:[EMAIL PROTECTED]] Sent: Monday, September 10, 2001 7:39 PM Subject: Re: nsv vs. ns_cache vs. ns_share +-- On Sep 10, Jerry Asher said: > I'm not sure. It's true that the writer shouldn't just free the table -- I > guess that readers need to refcount it (and unrefcount it), You cannot, in C, atomically modify a reference count in memory. It might be possible to do so from assembler on some platforms, but a portable implementation must use a lock..
Re: [AOLSERVER] nsv vs. ns_cache vs. ns_share
+-- On Sep 10, Sean Owen said: > This is true, but is atomicity really required? If you don't mind the memory > being taken up for a few extra cycles, it seems to me that if you point the > API at the new version of the hash table, you can poll the reference count > for the old version once a second until it is zero, and then safely free the > memory. What's a little busywaiting among friends? What if two readers try to decrement the reference count simultaneously? One of the decrements will be missed and you'll never stop polling.
Re: [AOLSERVER] nsv vs. ns_cache vs. ns_share
Ah, there's the rub. Silly me. Sean -Original Message- From: Rob Mayoff [mailto:[EMAIL PROTECTED]] Sent: Monday, September 10, 2001 9:38 PM To: Sean Owen Cc: '[EMAIL PROTECTED]' Subject: RE: nsv vs. ns_cache vs. ns_share +-- On Sep 10, Sean Owen said: > This is true, but is atomicity really required? If you don't mind the memory > being taken up for a few extra cycles, it seems to me that if you point the > API at the new version of the hash table, you can poll the reference count > for the old version once a second until it is zero, and then safely free the > memory. What's a little busywaiting among friends? What if two readers try to decrement the reference count simultaneously? One of the decrements will be missed and you'll never stop polling.
Re: [AOLSERVER] nsv vs. ns_cache vs. ns_share
>I have verified the lock contention problem by viewing mutex statistics. >The >offending nsv bucket got 100 times more locks than any other, and under >heavy load was busy up to 48% of the time. Not good. > >I also verified that the hashtable in question was the primary source of >the >locks. It's a single nsv. It can be (and frequently is) used multiple times >per page. I did a little load/mutex testing and these are my results: Setting: load test was using ab on local host and was using existing app that has approx 70 main nsv arrays. For test I preloaded one of the arrays with 100,000 extra distince values at server startup in addition to other values that would be referenced on the page that ab would call. The targeted page would reference the *heavy* array 13 times during test in addition to a few other refs to other nsv in bucket. The page that was loaded had ~100 nsv locks required for full load. Am using aolserver 3.3.1 on linux 2.4.3 kernel. I have 11 buckets setup and statistic/mutex tracking set on in config file. The tested page does 1 db query. Page Load Results for 1000 pages at concurrency 5 nsd7.6 returned 85 page/sec at 613 kb/sec nsd8.x returned 63 page/sec at 452 kb/sec Mutex results: 7.6 nsv array that contained the 100,000 entries grabed 17,100 locks during test and was busy 106 times. As a side note another nsv that had under 200 entries grabbed ~37,000 locks during test and was busy 192 times. 8.x test while slower in performance had less mutex contention with the targeted nsv with 100,000 entries only waiting 10 times for the 17,000 locks. The other entry that did wait 192 times was also reduced to 105 times I have previously load tested this setup with over 1,000,000 objects loaded (made the process over 400 Meg :) and did not notice any significant performance decrease compared to non heavy cache. I am not convinced that the number of entries in the hash is what is adversly effecting mutex contention. I'm also not convinced that load is effected too much by waiting but Im interested in what may be causing these issues. Can you post more info ...and possibly offending code samples? Best regards, Carl Garland _ Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp
Re: [AOLSERVER] nsv performance characteristics - nscache instead?
In the interests of simplicity, if your site is really going to get "light to modest traffic,", you may find that the system performs adequately without using the nsv arrays for this data. I'd say that unless you're looking at more than 100 page reads per minute, you might be just fine, especially if you use the ACS query memoization facility. OK, maybe it should be more like 50 page reads per minute, but still unless you're really starved for hardware speed, this is very doable. If you find you are hardware-limited, consider buying faster hardware first -- you can buy a really fast machine for $2000 to $3000; what is your time worth? (Unless you're building infrastructure you intend to reuse later, in which case your time would be seen as an investment, rather than a direct cost.) If you design some abstraction into your data access routines, you should be able to add caching later without having to rip out huge tracts of land. Pete.
[AOLSERVER] nsv needs C API Re: [AOLSERVER] ns_set,
On Fri, Nov 08, 2002 at 07:36:33AM -0800, Jim Wilcoxson wrote: > Creating a TCL-accessible array in a C module is trival. Just pass Ah, thanks! Sometimes having one simple example in front of you is so much more useful than any number of man pages. :) > You use Tcl_GetVar to read simple TCL vars in C, or Tcl_GetVar2 to > read TCL array vars in C. Again, these can be local, global, or > ns_shares. Yet another reason why nsv's aren't the greatest thing > since sliced bread. ;) Well, AOLserver really SHOULD ship with a C API to nsv, but since it doesn't, I created my own partial one. It was pretty easy. But then, I took the shortcut of often using Ns_TclEval in my C nsv wrapper functions. If I was doing it as part of AOLserver I'd instead create a real C API and change the nsv Tcl commands to use it. -- Andrew Piskorski <[EMAIL PROTECTED]> http://www.piskorski.com
Re: [AOLSERVER] nsv needs C API Re: [AOLSERVER] ns_set,
In a message dated 11/8/2002 10:50:19 AM Eastern Standard Time, [EMAIL PROTECTED] writes: On Fri, Nov 08, 2002 at 07:36:33AM -0800, Jim Wilcoxson wrote: >Creating a TCL-accessible array in a C module is trival. Just pass Ah, thanks! Sometimes having one simple example in front of you is so much more useful than any number of man pages. :) >You use Tcl_GetVar to read simple TCL vars in C, or Tcl_GetVar2 to >read TCL array vars in C. Again, these can be local, global, or >ns_shares. Yet another reason why nsv's aren't the greatest thing >since sliced bread. ;) Well, AOLserver really SHOULD ship with a C API to nsv, but since it doesn't, I created my own partial one. It was pretty easy. But then, I took the shortcut of often using Ns_TclEval in my C nsv wrapper functions. If I was doing it as part of AOLserver I'd instead create a real C API and change the nsv Tcl commands to use it. Perhaps nsv should be replaced with the svar work Zoran had worked on? You could provide backwards compatibility wrappers of course. What do you think Zoran? - n
Re: [AOLSERVER] nsv needs C API Re: [AOLSERVER] ns_set,
On Fri, Nov 08, 2002 at 05:34:43PM -0500, Nathan Folkman wrote: > In a message dated 11/8/2002 10:50:19 AM Eastern Standard Time, > [EMAIL PROTECTED] writes: > > Well, AOLserver really SHOULD ship with a C API to nsv, but since it > > doesn't, I created my own partial one. It was pretty easy. But then, > > I took the shortcut of often using Ns_TclEval in my C nsv wrapper > > functions. If I was doing it as part of AOLserver I'd instead create > > a real C API and change the nsv Tcl commands to use it. > Perhaps nsv should be replaced with the svar work Zoran had worked on? You > could provide backwards compatibility wrappers of course. What do you think > Zoran? I'm not sure, but I think Zoran already DID make his stuff backwards compatabile with the nsv_* API. I haven't tried his (way cool, btw!) Tcl Thead Extension yet, but last I checked its tls code was organized similarly to the nsv code, no C API. -- Andrew Piskorski <[EMAIL PROTECTED]> http://www.piskorski.com
Re: [AOLSERVER] nsv needs C API Re: [AOLSERVER] ns_set,
In a message dated 11/8/2002 5:42:25 PM Eastern Standard Time, [EMAIL PROTECTED] writes: I'm not sure, but I think Zoran already DID make his stuff backwards compatabile with the nsv_* API. I haven't tried his (way cool, btw!) Tcl Thead Extension yet, but last I checked its tls code was organized similarly to the nsv code, no C API. Maybe Zoran would be willing to add some C hooks, and we could look at replacing our nsv implementation with his. Your call Zoran. ;-) - n
Re: [AOLSERVER] nsv needs C API Re: [AOLSERVER] ns_set,
On Friday 08 November 2002 23:34, you wrote: > Perhaps nsv should be replaced with the svar work Zoran had worked on? You > could provide backwards compatibility wrappers of course. What do you think > Zoran? The code in current threading extension, implementing the thread shared variables (aka nsv_*) has already all compatibility wrappers built in. One can compile the Tcl threading extension for AOLserver and this will turn on the compatibility wappers automatically (beside providing a very nice thread-abstraction in addition). The tsv::* differs from the original nsv in terms of much larger command set, built-in shared Tcl objects and other goodies, while maintaining the backward compatibility. I have no external-defined C-API but I can refactor to code a little. This would be no problem at all. I would say, one could take this into consideration for one of the next releases. Cheers Zoran
Re: [AOLSERVER] nsv needs C API Re: [AOLSERVER] ns_set,
Hi - this sounds interesting. Can an ns_share emulation be implemented on top of this new shared var mechanism with good performance, i.e., at least equivalent to TCL7.6 ns_shares? Jim > > On Friday 08 November 2002 23:34, you wrote: > > Perhaps nsv should be replaced with the svar work Zoran had worked on? You > > could provide backwards compatibility wrappers of course. What do you think > > Zoran? > > The code in current threading extension, implementing the thread shared > variables (aka nsv_*) has already all compatibility wrappers built in. > One can compile the Tcl threading extension for AOLserver and this will > turn on the compatibility wappers automatically (beside providing a very > nice thread-abstraction in addition). > The tsv::* differs from the original nsv in terms of much larger command set, > built-in shared Tcl objects and other goodies, while maintaining the > backward compatibility. > > I have no external-defined C-API but I can refactor to code a little. > This would be no problem at all. I would say, one could take this into > consideration for one of the next releases. > > Cheers > Zoran >
Re: [AOLSERVER] nsv needs C API Re: [AOLSERVER] ns_set,
Since we are talking about these useful global data structures, I want to again bring up a question. Jim once mentioned AOL's internal use of what was called a 'network var', is there any chance the ideas or code behind that could be released at some point? --Tom Jackson
Re: [AOLSERVER] nsv needs C API Re: [AOLSERVER] ns_set,
On Saturday 09 November 2002 02:26, you wrote: > Hi - this sounds interesting. Can an ns_share emulation be > implemented on top of this new shared var mechanism with good > performance, i.e., at least equivalent to TCL7.6 ns_shares? > I doubt that we will get the function/performance of ns_share as in 7.6. It was an entirely differen beast, as you know. I might design a way of getting the regular Tcl variable bound to a shared variable under the hood, so one can get more/less what ns_share offered. You'd eventually be able to do: tsv::share sharedVariable localVariable and then do something like set localVariable(myindex) myValue puts $localVariable(myindex) in your script. This I may do with variable traces or some other scheme, I'm not yet sure about that. Is the nsv_* something you cannot use as-is? I find it very convenient. The only thing I do not like at the moment is the need of an extra command to access it. This would be solved by the above approach. I must admit, I'm just playing with the idea. I did not give it a serious thinking, though. Cheers Zoran
Re: [AOLSERVER] nsv needs C API Re: [AOLSERVER] ns_set,
On Saturday 09 November 2002 02:26, you wrote: > Hi - this sounds interesting. Can an ns_share emulation be > implemented on top of this new shared var mechanism with good > performance, i.e., at least equivalent to TCL7.6 ns_shares? > Oh, yes, I forgot to add... I'll be away from the office until Thursday and won't be able to check my mail. So if you have some more questions, we might have to wait couple of days. Cheers Zoran
Re: [AOLSERVER] nsv needs C API Re: [AOLSERVER] ns_set,
I looked a little at the TCL C binding mechanism, and it seemed like that would be a good way to do ns_shares. One problem I noticed is that there is no way for a TCL var to "not exist" if it is bound to a C variable, ie, [info exists blah] will always be true for a TCL var bound to a C var, but not always true for ns_shares. Since the TCL core already has all this stuff in it about binding TCL vars to C vars, it seems plausible to use it for ns_shares and get 7.6-like performance without needing traces. I had to look at & halfway understand the ns_share changes to the TCL 7.6 core in order to fix the "malformed bucket chain" error. I realize it's a hack to the TCL core, but it didn't seem that horrible for the benefits it yields. It didn't seem like a bigger hack than the 8x trace implementation, though I understand that the 7.6 way is part of the core and the 8x way is independent of the core. We have lots of TCL code and lots of ns_shares on our site. So aside from my philosophical dislike of nsv's, there's just too much code for us to change, both time-wise and risk-wise. IMO, an easy-to-use shared variable store is one of the greatest features of AOLServer. ns_share, to me, is the right paradigm. Maybe the TCL core guys can see their way to implementing an easy shared var mechanism that works like ns_share. I can dream... :) Jim > > On Saturday 09 November 2002 02:26, you wrote: > > Hi - this sounds interesting. Can an ns_share emulation be > > implemented on top of this new shared var mechanism with good > > performance, i.e., at least equivalent to TCL7.6 ns_shares? > > > > I doubt that we will get the function/performance of ns_share > as in 7.6. It was an entirely differen beast, as you know. > > I might design a way of getting the regular Tcl variable bound > to a shared variable under the hood, so one can get more/less > what ns_share offered. > > You'd eventually be able to do: > >tsv::share sharedVariable localVariable > > and then do something like > >set localVariable(myindex) myValue >puts $localVariable(myindex) > > in your script. This I may do with variable traces or > some other scheme, I'm not yet sure about that. > > Is the nsv_* something you cannot use as-is? > I find it very convenient. The only thing I do not > like at the moment is the need of an extra command to > access it. This would be solved by the above approach. > I must admit, I'm just playing with the idea. I did not > give it a serious thinking, though. > > Cheers > Zoran >
Re: [AOLSERVER] nsv needs C API Re: [AOLSERVER] ns_set,
On Saturday 09 November 2002 19:43, you wrote: > Since the TCL core already has all this stuff in it about binding TCL > vars to C vars, it seems plausible to use it for ns_shares and get > 7.6-like performance without needing traces. Ehm... the Tcl bindings *use* traces internally, i.e. on the C-level. This is exactly what I wanted to do for tsv::share. A very similar approach is already been deployed in the ns_share implementation for the 8x series nsd. I think this (trace-approach) would result in reasonable performance, albeit not as fast as 7.6. > > I had to look at & halfway understand the ns_share changes to the TCL > 7.6 core in order to fix the "malformed bucket chain" error. I > realize it's a hack to the TCL core, but it didn't seem that horrible > for the benefits it yields. It didn't seem like a bigger hack than > the 8x trace implementation, though I understand that the 7.6 way > is part of the core and the 8x way is independent of the core. The 7.6 ns_share was a *deep* hack into the Tcl internals. It is difficult to understand and maintain. Just look at all these locks arround! Locks in one function, unlocks in other. Brrr... One gets lost pretty fast. Benefits? I'd say, on the Tcl-level there would be no difference between the ns_share and trace-enabled nsv_* (or the tsv::*). Speed? Yes, I admit. it would be slower. But how much? Given the skyrocketing CPU speeds, I'm more concerned about the implementation maintainability then some-% speed penalty. > > We have lots of TCL code and lots of ns_shares on our site. So aside > from my philosophical dislike of nsv's, there's just too much code for > us to change, both time-wise and risk-wise. Is the "philosophical dislike" based on the Tcl-side of the matter (i.e. need for wrapper commands) or the underlying implementation? > > IMO, an easy-to-use shared variable store is one of the greatest > features of AOLServer. ns_share, to me, is the right paradigm. Maybe > the TCL core guys can see their way to implementing an easy shared var > mechanism that works like ns_share. I can dream... :) > Well, who knows what future might bring ;) >From my side, I will go an try the tsv::share command as described. It should offer more/less the same on the Tcl-level as the ns_share. Then we might do some performace tests, to see what happens really. Again, I yet have to make some deeper thinking about the real implementation. There may be a hidden catch-22 somewhere, who knows? Cheers Zoran P.S. Ok, now I really have to go. I'll be back on Thursday. Bye.
Re: [AOLSERVER] nsv needs C API Re: [AOLSERVER] ns_set,
> > On Saturday 09 November 2002 19:43, you wrote: > > > Since the TCL core already has all this stuff in it about binding TCL > > vars to C vars, it seems plausible to use it for ns_shares and get > > 7.6-like performance without needing traces. > > Ehm... the Tcl bindings *use* traces internally, i.e. on the C-level. Okay. I am showing my ignorance then. :) > Speed? Yes, I admit. it would be slower. But how much? Given the > skyrocketing CPU speeds, I'm more concerned about the implementation > maintainability then some-% speed penalty. The test I ran to compare 8x with 7.6x was a 10-line loop, around 400K iterations, setting 2 ns_share arrays. Because of TCL 8x compilation, I expected it to go faster, but instead, it was around 3x slower. That doesn't mean our site will be 3x slower of course, but it didn't encourage me to jump on the 8x bandwagon - that's all. > > We have lots of TCL code and lots of ns_shares on our site. So aside > > from my philosophical dislike of nsv's, there's just too much code for > > us to change, both time-wise and risk-wise. > > Is the "philosophical dislike" based on the Tcl-side of the matter > (i.e. need for wrapper commands) or the underlying implementation? I am spoiled by having true shared variables that act like TCL variables in all aspects, ie, can be passed w/o the caller knowing whether they are shared for example, writing a ton of code with that paradigm, and then having it taken away and given "a way to share data among threads", which is not a TCL variable. To me, nsv's are a very different animal. For people just starting out, it's probably not a big deal. They can write their code to whatever shared data interface is available. We have 933 ns_share statements across 407 TCL source files, so the impact of changing all that code is very high for us. I do appreciate that you have the ability to consider and/or implement alternate shared var mechanisms. I can only talk about it. :) Jim
Re: [AOLSERVER] nsv needs C API Re: [AOLSERVER] ns_set,
In a message dated 11/10/2002 3:09:41 AM Eastern Standard Time, [EMAIL PROTECTED] writes: The 7.6 ns_share was a *deep* hack into the Tcl internals. It is difficult to understand and maintain. Just look at all these locks arround! Locks in one function, unlocks in other. Brrr... One gets lost pretty fast. Benefits? Zoran's right - the 7.6 ns_share code was a "deep" hack. Here's a comment in tcl7.6/generic/tclVar.c I wrote years ago about how it works: /* * The Var structure has an Ns_Mutex pointer which if not null is * locked in LookupVar and unlocked later when safe. This is a * poor programming style - locking and unlocking at different * procedure levels - but's it's necessary with all the weirdness * that LookupVar does. If the shared variable is an array the * lock is shared for the whole array. Note that to avoid even more * craziness the shared Var structure refCount is set to 1 instead * of 0 here to ensure it is *never* actually deleted, * even if the contents (array or scalar) are. This means this is * a memory and lock leak: * * set n 0 ; while 1 {ns_share $n ; set $n 1 ; unset $n} */ Oh well. Briefly, this is how we got here from what I can remember: Naviserver 1.0 - Tcl7.3 single threaded, no shared vars that I can remember Naviserver 2.0 - Tcl7.4 hacked for thread safety only, shared data with the simple "ns_var" command (still exists) AOLserver 2.1 - Tcl7.4 Severly hacked (much more than what you see in 7.6) to share nearly everything. Basically, the Tcl interp was split into private and shared parts - the shared parts included the Tcl command/proc tables and the global variables. Yes - all global variables, not special shared variables, which meant simple things like the global errorInfo didn't work right AOLserver 2.2->2.3 - Shared globals now an option (off by default) and ns_share introduced. The Tcl7.4 core was further hacked to distiguish between local, global shared, global private, and the new shared vars. AOLserver 3.0 - Tcl 7.6 code hacked for thread safety and to support the ns_share command only. 3.0 came out around the same time as 8.1. People were asking for 8.1 so I looked at hacking the 8.1 var code as was done in 7.6. This turned out to be hard - I couldn't isolate all the changes to tclVar.c because, for example, variables now showed up in literal tables as part of byte compiling and such. Anyway, we wanted to stop hacking the Tcl core going forward. To cover existing use of ns_share, Brent Welch from Scriptics wrote a variable trace version. It worked but wasn't as efficient as the direct support in 7.6. AOLserver 3.4 (maybe earlier?) - Added the nsv interface. This was based on some of the command-based shared data interfaces we had created at AOL. So, seems like the variable tracing ns_share in AOLserver 3.x and 4.0 could be used as a basis to extend nsv but it may not approach the performance of the 7.6 shares. If ns_share is really very useful, perhaps the TIP process could be used to consider adding support in the Tcl core. -Jim
[AOLSERVER] use nscache! ( was [AOLSERVER] nsv performance characteristics - nscache instead? )
Dave Siktberg wrote: > > I am using nsv arrays to hold session data across multiple page accesses, etc (snipped for brevity..) > Is there any way to monitor the amount of space consumed by nsv arrays at > any point in time? What should I do to monitor the performance impact of my > nsv use (other than the mutex monitoring), and perhaps to trigger more > aggressive purges - or rewrites :( - when needed? > > I realize that nscache provides similar facilities. There is so much else > on my plate, and my facility with Linux internals is so limited, I hesitate > to go down the path of installing it. Would it provide a major improvement, > so that I should invest that time and energy? Dave, the nscache stuff works very well and installs pretty easily. >From your descriptions above, I predict you would have a much easier time switching to the nscache stuff instead of trying to cook up something yourself with nsv arrays. -mike