User-specific data, extending property groups



Working through getting all the properties that the client needs to
display the stacker, I ran into a stumbling block with:

 block.clickedTimestamp
 block.ignoredTimestamp

These actually are UserBlockData properties, and are thus user specific
and cannot be cached in the data-model cache.

Doing:

 @DMProperty(cached=false)
 long getClickedTimestamp() {
     return view.getUserBlockData().getClickedTimestampAsLong();
 }

Hits two problems:

 A) We always load the BlockView() from the system viewpoint, since we
    want to return user-independent data for caching and let the 
    data model filter that down to what each user can see.

 B) If everything else is cached, then loading and populating the
    BlockView just to get the clicked timestamp from the 
    UserBlockData is prohibitively expensive.

If we instead we go with

 @DMProperty(cached=false)
 long getClickedTimestamp() {
     if (viewpoint instanceof UserViewpoint) {
         User user = ((UserViewpoint)viewer);
         /* Lookup UserBlockData for user and blockId */
         return userBlockData.getClickedTimestampAsLong();
     } else {
         return -1;
     }
 }

We still hit two problems:

 A) Even though the BlockView wasn't used, it still got loaded
    by the initialization step run before getClickedTimestamp was
    called().
 B) If we also added getIgnoredTimestamp() it would also look up
    the UserBlockData, separately.

The second issue makes me think that this is related to the group
support I added a while ago which allows a bunch of properties to be
computed and cached at once. This currently looks like

    private static final int CONTACTERS_GROUP = 1;

    private boolean currentTrackFetched;
    private TrackHistory currentTrack;

    private void ensureCurrentTrack() {
        if (!currentTrackFetched) {
             /* Bunch of work to look up currentTrack */
	}
    }
	
    @DMProperty(group=CURRENT_TRACK_GROUP)
    public TrackDMO getCurrentTrack() {
 	ensureCurrentTrack();
	
	if (currentTrack != null)
   	    return session.findUnchecked(TrackDMO.class, currentTrack.getTrack().getId());
	else
	    return null;
    }
	
    @DMProperty(group=CURRENT_TRACK_GROUP)
    public long getCurrentTrackPlayTime() {
 	 ensureCurrentTrack();
		
	 if (currentTrack != null)
	      return currentTrack.getLastUpdated().getTime();
 	 else
 	      return -1;
	 }
    }

But what if we extended it so we could do:

    private TrackHistory currentTrack;

    @DMInit(group=CURRENT_TRACK_GROUP)
    private void initCurrentTrack() {
        /* Bunch of work to look up currentTrack */
    }
	
    @DMProperty(group=CURRENT_TRACK_GROUP)
    public TrackDMO getCurrentTrack() {
	if (currentTrack != null)
   	    return session.findUnchecked(TrackDMO.class, currentTrack.getTrack().getId());
	else
	    return null;
    }
	
    @DMProperty(group=CURRENT_TRACK_GROUP)
    public long getCurrentTrackPlayTime() {
	 if (currentTrack != null)
	      return currentTrack.getLastUpdated().getTime();
 	 else
 	      return -1;
	 }
    }

Then, one step more of extension allows:

    @DMInit(group=USER_BLOCK_DATA_GROUP, initMain=false) 
    long initUserBlockData() {
        if (viewpoint instanceof UserViewpoint) {
            User user = ((UserViewpoint)viewer);
            /* Lookup UserBlockData for user and blockId */
        }
    }

    @DMProperty(cached=FALSE, group=USER_BLOCK_DATA_GROUP)
    long getClickedTimestamp() {
        return userBlockData.getClickedTimestampAsLong();
    }

    @DMProperty(cached=FALSE, group=USER_BLOCK_DATA_GROUP)
    long getClickedTimestamp() {
        return userBlockData.getIgnoredTimestampAsLong();
    }

Which I'm pretty happy with. 
                                                  - Owen

Attachment: signature.asc
Description: This is a digitally signed message part



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]