Forum OpenACS Development: xotcl-core variable scope with ad_proc methods and filters

Adding a filter using ad_proc seems to break the scope of variables. instvars are not available if a class has a filter defined using ad_proc. Using proc it works ok. Sample Code This breaks CollabPage instvar:
 CollabPage ad_proc fetch_latest_revision_if_no_live_revision {args} {
    Documentation String
} {
      set method [self calledproc]
      my log "collabpage filter method='${method}'"
      if {$method eq "fetch_object"} {
           array set the_args $args
           if {$the_args(-revision_id) eq "0"} {
                set the_args(-revision_id) "[content::item::get_best_revision -\
item_id $the_args(-item_id)]"
           }
           eval [concat next [array get the_args]]
      } else {

          next
      }
  }

  CollabPage filter fetch_latest_revision_if_no_live_revision
For example CollabPage instvar storage_type does not find the storage_type instvar. (CollabPage is a subtype of ::xowiki::Page which is a subtype of ::Generic::CrClass) Using Collabpage proc .... instead works fine. I think the filters here make sense since I want to capture the call to fetch_object without having to rewrite all the code. I also just want to get something working without redesigning xotcl-core. Maybe once I get it working, I an better evaluate changes to xotcl-core that might make it more flexible.
Adding a filter using ad_proc seems to break the scope of
variables. instvars are not available if a class has a
filter defined using ad_proc.

i am not convinced: By using

CollabPage filter fetch_latest_revision_if_no_live_revision
you define a filter on the class object. If you want to define a filter for the instances of the class (the pages), use instfilter instead (like proc + instproc).

I think the filters here make sense since I want to capture > the call to fetch_object without having to rewrite all the
code

I see no need for a filter here. Why not defining CollabPage proc fetch_object ?

in general, i think it performance-wise not a good idea to add at this level more trivial sql queries, but to add the "best revision" logic to the sql query in fetch (see cvs head).

Btw, talking about tons if small queries: we have currently high-season on our learn system (1200+ active users), a load we handled quite easily with our system in the past (response time less than 0.2 secs). This time, we have as well course assessments (currently for 1200 courses), but this brings as well our system to its knees (uncached permission checks take sometimes more than 5 secs). Assessment needs a rewrite for being scalable.

Gustaf,

OK, I'll try to figure it out :)

Like I said, fetch_object is a complex method, so I don't want to keep rewriting stuff like that for a simple change, nor do I want to add unlimited parameters to make the base method infinitely flexible. That just leads to a different kind of unmaintainability.

Perhaps CR objects are just complex and hard to maintain.

When you define the proc, it can do a "next" the same style as in your example....
I don't know what permissions checks have to do with the design of assessment. It should only be doing a check on the base object you are dealing with.

In general all the joins in assessment on the *i views need to be rewritten instead to use the type specific table, and join cr_items, cr_revisions as necessary.

Maybe you can post some of the slow queries in a new thread?

The problem is when an questionnaire is loaded, it first loads all sections, then it loads for all sections the questions, all from the CR, one tuple at a time. In the best of all possible worlds, that could be single SQL query producing section objects containing item objects.

Once the machine is hammered to its knees, simple SQL queries taking before a few milliseconds can take up to a few seconds. So it is not just a single query which has to be optimized, it the sheer quantity of queries with their individual overheads.

Currently, we are back to normal:

Active Users: 1072 users in 94 communities active in last 10 minutes, 3200 in last 10 hours (6361 total)
Current System Activity: 4423 exercises last 15 mins, 28.6 views/sec, 1.77 views/min/user, avg. view time: 33.9
Current System Load: 13:35:10 up 62 days, 21:03, 4 users, load average: 5.41, 10.51, 12.49
Current Avg Response Time/sec: 0.20 (last minute), 1.14 (last 30 minutes), 0.72 (last hour), 0.28 (last 10 hours)

Yes, getting every question as a separate query is a bad idea!
Collapse
5: Modifying behavior of (response to 1)
Posted by Dave Bauer on
Gustaf,

I am not sure, forcing the selection of latest revision will provide expected behavior.

I am working on an application that does not automatically publish revisions, an administrator must click the button to set a revision live.

In this case, I want admins to be able to read the unpublished revisions but not anyone else.

The reason I took to changing how fetch object works, is that I could not find a straightforward way to modify the behavior that generates the links to the object in the admin pages.

This is where it uses select_instances_query. I created a method on my class to do this query which is fine.

Now I have to figure out how to modify the link to an individual page to go to the specific revision, based on my query, and fetch_object can remain unchanged. In the regular list of objects (xowiki/www/admin/list.tcl) it just uses the name of the page, and I don't see the best way to modify this. Any advice?

Collapse
Posted by Gustaf Neumann on
Dave,

i just checked in a small modification of xowiki + xotcl-core that handles items with different publish_statues differently. It distinguishes between publish_status 'production' and 'ready'. The status can be toggled from the admin pages. When the new package_parameter "production_mode" is set, an edit results in a page in state "production" which needs to be made "ready" from the admin pages. The various aggregators from xowiki (e.g. weblog, last_visited, ...) don't display pages in 'production' mode.

It is not completely clear to me, how this is supposed to interact with the live_revision, and what to do on links pointing to pages not 'ready'.