1 |
On Sun, Nov 20, 2005 at 12:50:25AM +0900, Jason Stubbs wrote: |
2 |
<regarding FsLocks and keeping fds open while unlocked> |
3 |
> > > Also, with a long running portage |
4 |
> > > process and badly written code, it'd be quite easy to run out of fds... |
5 |
> > |
6 |
> > All locking code (stable included) has this potential though- it's not |
7 |
> > something limited to this implementation. |
8 |
> |
9 |
> I still don't see why fds should remain open after all locks are released. |
10 |
> What my point above is about is that if some external process creates a bunch |
11 |
> of FsLock objects that it keeps around to obtain future locks (bad design, |
12 |
> but) fds will quickly become used up when they are not actually being used |
13 |
> for anything. |
14 |
How about a configurable? |
15 |
|
16 |
From where I'm sitting, running out of fds *really* shouldn't occur. |
17 |
This locking is strictly fs orientated, synchronization points on the |
18 |
fs shouldn't be too many. |
19 |
|
20 |
Via a configurable, we can avoid open/close for every unlocked -> lock |
21 |
and lock -> unlocked transition; if fd exhaustion becomes an issue, |
22 |
we can just modify the class to ignore the configurable, so that it |
23 |
falls back to open/close during transitions. |
24 |
|
25 |
Compromise of sorts, plus it's probably useful for the class. :) |
26 |
|
27 |
Offhand... it's a bit nuts, but conversion of stable to the class |
28 |
based instance might be worthwhile, rather then the crap func route we |
29 |
have right now. |
30 |
|
31 |
One issue though is that portage_locks will cycle through flock/lockf, |
32 |
then falling back to the evil hardlink locking- this code is strictly |
33 |
flock. Thoughts on trying to clean up that crap in stable, or just |
34 |
leave the mess as it is and try and replace it down the line? |
35 |
|
36 |
> > Code needs further work if it's going into stable imo. |
37 |
> > |
38 |
> > Reason I wanted the code split off from 3.0 and backported was to show |
39 |
> > a file based approach rather then trying to do scans at load up. |
40 |
> |
41 |
> So, off topic then, eh? ;) I should actually take the code for a spin then to |
42 |
> see how it works. |
43 |
Not off topic, just clarifying why I nudged alec to split this off for |
44 |
stable. :) |
45 |
|
46 |
I'd like to keep the plugins handling on disk the same between 2.0 and |
47 |
3.0, so if we're adding a true pluging registry to 2.0, common code |
48 |
_hopefully_ can be shared. :) |
49 |
|
50 |
<relevant code> |
51 |
if plugin_type == None: |
52 |
ptypes = [x for x in os.listdir(plugins_dir) if x.endswith(PLUGINS_EXTENSION) ] |
53 |
|
54 |
len_exten = len(PLUGINS_EXTENSION) |
55 |
for x in ptypes: |
56 |
c = RawConfigParser() |
57 |
c.read(os.path.join(plugins_dir, x.lstrip(os.path.sep))) |
58 |
if raw: |
59 |
d[x[:-len_exten]] = c |
60 |
else: |
61 |
d[x[:-len_exten]] = dict([(y, dict(c.items(y))) for y in c.sections()]) |
62 |
|
63 |
> Hmm.. I know the dict zipping bit, but no I can't see what it's doing. "x" is |
64 |
> defined 6 lines above and seems to be a ptype. From what I know so far, I |
65 |
> guess an example would be "cache"? |
66 |
Yep, cache would be an example. |
67 |
|
68 |
> raw is a parameter/undocumented and d is the return type. This is what I mean |
69 |
> by not readable. (Sorry to be harsh/dumb) |
70 |
Nah, the code honestly was something of a dump. |
71 |
A refactoring would be useful, as would code feedback :) |
72 |
|
73 |
> |
74 |
> > > > > + finally: |
75 |
> > > > > + if locking: |
76 |
> > > > > + plug_lock.release_read_lock() |
77 |
> > > > > + if plugin_type != None: |
78 |
> > > > > + return d[plugin_type] |
79 |
> > > > > + return d |
80 |
> > > > > |
81 |
> > > > > Not sure about having different return types... |
82 |
> > > > |
83 |
> > > > Agreed. |
84 |
> > > |
85 |
> > > So one method for querying what plugin types are available and another |
86 |
> > > for querying plugins of a given type? |
87 |
> > |
88 |
> > Or one for querying the full tree, one for pulling a specific |
89 |
> > branch... |
90 |
> |
91 |
> Or all three? ;) |
92 |
> |
93 |
> This is a difference in style, I guess. A list of plugin types plus a method |
94 |
> to enumerate registered plugins for each type allows one to create a tree of |
95 |
> plugins on one's own. Providing the tree of plugins means one has to extract |
96 |
> information from a return and then throw away the rest. Performance-wise |
97 |
> they're probably both about the same when talking the non-catered case... |
98 |
Offhand... list of plugin types isn't known. The class is generic, |
99 |
locking down the plugin types allowed should/would be implemented in a |
100 |
derivative class, or via some proxy_it evilness. |
101 |
|
102 |
> > Curious, qualms about using a massively cleaned up version of this? |
103 |
> > The reason I wanted this seperated out and backported was to go with |
104 |
> > an actual registry, and abuse the existing code- specific complaints |
105 |
> > with that route, beyond patch sucking? |
106 |
> |
107 |
> None here. For what it's worth at this late stage, this patch is much better |
108 |
> than my attempt. :) |
109 |
|
110 |
This is version 3 of the savior plugins registry. You *really* do not |
111 |
want to see the first two I created (hence them never being in cvs). |
112 |
It's a fun bit to attempt :) |
113 |
|
114 |
So... assuming a plugin registry with on disk files is an agreeable |
115 |
approach, what would be the initial targets? Cache comes to mind, but |
116 |
what else? |
117 |
|
118 |
The problem with a registry is it just points at the func/code to load |
119 |
up; for elog (fex), it's not binding any configuration information to |
120 |
it- it *could* be managed by pointing at a func that holds the |
121 |
configuration info, but that's massively unclean (plus it'll stomp on |
122 |
3.0 goals of code/config seperation). |
123 |
~harring |