• Views
  • Iteration Report
  • My Iteration Report
  •  
OMERO.server
  • Login
  • Help/Guide
  • About Trac
  • Preferences
  • Wiki
  • Timeline
  • Roadmap
  • Browse Source
  • View Tickets
  • Search

Context Navigation

  • ← Previous Changeset
  • Next Changeset →

Changeset 1966

Show
Ignore:
Timestamp:
12/12/07 19:44:06 (12 months ago)
Author:
callan
Message:
  • ThumbnailService rework which removes the dependence on the rendering bean; we're now using the renderer directly. (#848)
  • Passivation has now been turned back on for the stateful beans, this should clear up any lingering memory leaks. (#769)
Location:
trunk/components
Files:
7 modified

  • rendering/src/omeis/providers/re/Renderer.java (modified) (5 diffs)
  • server/resources/ome/services/service-ome.api.IThumb.xml (modified) (1 diff)
  • server/src/ome/api/local/LocalQuery.java (modified) (1 diff)
  • server/src/ome/logic/PixelsImpl.java (modified) (1 diff)
  • server/src/ome/logic/QueryImpl.java (modified) (1 diff)
  • server/src/ome/services/RenderingBean.java (modified) (21 diffs)
  • server/src/ome/services/ThumbnailBean.java (modified) (16 diffs)

Legend:

Unmodified
Added
Removed
  • trunk/components/rendering/src/omeis/providers/re/Renderer.java

    r1936 r1966  
    534534        RGBBuffer img = renderingStrategy.render(this, pd); 
    535535        stats.stop(); 
    536         log.info(stats.getStats()); 
    537         // TODO: is this the right place to log??? We want to have as little 
    538         // impact on performance as possible. 
     536        // TODO: Commenting this out for now. -- callan 
     537        //log.info(stats.getStats()); 
    539538        return img; 
    540539    } 
    … …  
    569568        RGBIntBuffer img = renderingStrategy.renderAsPackedInt(this, pd); 
    570569        stats.stop(); 
    571         log.info(stats.getStats()); 
    572         // TODO: is this the right place to log??? We want to have as little 
    573         // impact on performance as possible. 
     570        // TODO: Commenting this out for now. -- callan 
     571        //log.info(stats.getStats()); 
    574572        return img.getDataBuffer(); 
    575573    } 
    … …  
    918916                        "Unable to find default rendering model in enumerated list."); 
    919917            } 
    920             def.setModel(defaultModel); 
    921          
     918             
     919            // Unload the rendering model to avoid transactional headaches 
     920            RenderingModel unloadedModel = new RenderingModel(); 
     921            unloadedModel.setId(defaultModel.getId()); 
     922            unloadedModel.unload(); 
     923            def.setModel(unloadedModel); 
     924 
    922925            // Quantization settings 
    923926            QuantumDef quantumDef = def.getQuantization(); 
    … …  
    926929            quantumDef.setBitResolution(QuantumFactory.DEPTH_8BIT); 
    927930            def.setQuantization(quantumDef); 
    928          
     931 
    929932            // Reset the channel bindings 
    930933            resetChannelBindings(def, pixels, quantumFactory, buffer); 
    … …  
    964967        r.setQuantization(new QuantumDef()); 
    965968        r.setWaveRendering(createNewChannelBindings(p)); 
    966         r.setPixels(p); 
     969         
     970        // Unload the pixels object to avoid transactional headaches 
     971        Pixels unloadedPixels = new Pixels(); 
     972        unloadedPixels.setId(p.getId()); 
     973        unloadedPixels.unload(); 
     974        r.setPixels(unloadedPixels); 
    967975        return r; 
    968976    } 
  • trunk/components/server/resources/ome/services/service-ome.api.IThumb.xml

    r1748 r1966  
    2525        <constructor-arg><value>true</value></constructor-arg> 
    2626    <property name="ioService" ref="/OMERO/Thumbs"/> 
    27     <property name="renderingEngine" 
    28         ref="internal:omeis.providers.re.RenderingEngine"/> 
     27    <property name="IPixels" ref="internal:ome.api.IPixels"/> 
     28    <property name="pixelDataService" ref="/OMERO/Pixels"/> 
    2929    <property name="scaleService" ref="internal:ome.api.IScale"/> 
    3030    <property name="compressionService" ref="internal:ome.api.ICompress"/> 
  • trunk/components/server/src/ome/api/local/LocalQuery.java

    r1167 r1966  
    7373    void evict(Object object); 
    7474 
     75        void clear(); 
     76 
    7577    /** 
    7678     * Uses the Hibernate static method <code>initialize</code> to prepare an 
  • trunk/components/server/src/ome/logic/PixelsImpl.java

    r1949 r1966  
    121121    @Transactional(readOnly = false) 
    122122    public void saveRndSettings(RenderingDef rndSettings) { 
    123         iUpdate.saveObject(rndSettings); 
     123        iUpdate.saveAndReturnObject(rndSettings); 
    124124    } 
    125125 
  • trunk/components/server/src/ome/logic/QueryImpl.java

    r1949 r1966  
    9999    public void evict(Object obj) { 
    100100        getHibernateTemplate().evict(obj); 
     101    } 
     102 
     103    @RolesAllowed("user") 
     104    @Transactional(readOnly = false) 
     105    public void clear() { 
     106        getHibernateTemplate().clear(); 
    101107    } 
    102108 
  • trunk/components/server/src/ome/services/RenderingBean.java

    r1949 r1966  
    1212import java.io.ByteArrayOutputStream; 
    1313import java.io.IOException; 
    14 import java.io.PrintWriter; 
    1514import java.io.Serializable; 
    16 import java.io.StringWriter; 
    17 import java.io.Writer; 
    1815import java.util.ArrayList; 
    1916import java.util.List; 
    … …  
    3936import org.jboss.annotation.ejb.RemoteBinding; 
    4037import org.jboss.annotation.ejb.RemoteBindings; 
    41 import org.jboss.annotation.ejb.cache.Cache; 
    4238import org.jboss.annotation.security.SecurityDomain; 
    43 import org.jboss.ejb3.cache.NoPassivationCache; 
    4439import org.springframework.transaction.annotation.Transactional; 
    4540 
    … …  
    4742import ome.annotations.RevisionDate; 
    4843import ome.annotations.RevisionNumber; 
    49 import ome.api.ICompress; 
    5044import ome.api.IPixels; 
    5145import ome.api.ServiceInterface; 
    … …  
    5852import ome.io.nio.PixelsService; 
    5953import ome.logic.AbstractLevel2Service; 
    60 import ome.logic.SimpleLifecycle; 
    6154import ome.model.IObject; 
    6255import ome.model.core.Channel; 
    … …  
    8679 * <p> 
    8780 * The multi-threaded design of this component is based on dynamic locking and 
    88  * confinement techiniques. All access to the component's internal parts happens 
     81 * confinement techniques. All access to the component's internal parts happens 
    8982 * through a <code>RenderingEngineImpl</code> object, which is fully 
    9083 * synchronized. Internal parts are either never leaked out or given away only 
    … …  
    118111@LocalBinding(jndiBinding = "omero/local/omeis.providers.re.RenderingEngine") 
    119112@SecurityDomain("OmeroSecurity") 
    120 @Cache(NoPassivationCache.class) 
    121113@TransactionManagement(TransactionManagementType.BEAN) 
    122114@Transactional(readOnly = true) 
    … …  
    152144 
    153145    /** The pixels set to the rendering engine is for. */ 
    154     private transient Pixels pixelsObj; 
     146    private Pixels pixelsObj; 
    155147 
    156148    /** The rendering settings associated to the pixels set. */ 
    157     private transient RenderingDef rendDefObj; 
     149    private RenderingDef rendDefObj; 
    158150 
    159151    /** Reference to the service used to retrieve the pixels data. */ 
    … …  
    171163     */ 
    172164    private transient ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); 
     165 
     166    /** Notification that the bean has just returned from passivation. */ 
     167    private transient boolean wasPassivated = false; 
    173168     
    174169    /** 
    … …  
    202197     * Delegates to super class 
    203198     */ 
    204     @PostActivate 
    205199    @PostConstruct 
    206200    public void create() { 
    … …  
    208202    } 
    209203 
    210     /** lifecycle method -- {@link PrePassivate}. Disallows all passivation. */ 
     204    /** lifecycle method -- {@link PostPassivate}. */ 
     205    @PostActivate 
     206    public void postPassivate() { 
     207        log.info("***** Returning from passivation... ******"); 
     208        create(); 
     209        wasPassivated = true; 
     210        rwl = new ReentrantReadWriteLock(); 
     211    } 
     212 
     213    /** lifecycle method -- {@link PrePassivate}. */ 
    211214    @PrePassivate 
    212215    public void passivate() { 
    213         closeRenderer(); 
    214         getBeanHelper().passivationNotAllowed(); 
     216        log.info("***** Passivating... ******"); 
     217        closeRenderer(); 
     218        renderer = null; 
    215219    } 
    216220 
    … …  
    253257     */ 
    254258    @RolesAllowed("user") 
     259    @Transactional(readOnly = false) 
    255260    public void lookupPixels(long pixelsId) { 
    256         rwl.writeLock().lock(); 
    257  
    258         try { 
    259             this.pixelsObj = pixMetaSrv.retrievePixDescription(pixelsId); 
    260             closeRenderer(); 
    261             this.renderer = null; 
    262  
    263             if (pixelsObj == null) { 
    264                 throw new ValidationException("Pixels object with id " 
    265                         + pixelsId + " not found."); 
    266             } 
    267         } finally { 
    268             rwl.writeLock().unlock(); 
    269         } 
    270  
    271         if (log.isDebugEnabled()) { 
    272             log.debug("lookupPixels for id " + pixelsId + " succeeded: " 
    273                     + this.pixelsObj); 
    274         } 
     261        rwl.writeLock().lock(); 
     262 
     263        try { 
     264                pixelsObj = pixMetaSrv.retrievePixDescription(pixelsId); 
     265                closeRenderer(); 
     266                renderer = null; 
     267 
     268                if (pixelsObj == null) { 
     269                        throw new ValidationException("Pixels object with id " 
     270                                        + pixelsId + " not found."); 
     271                } 
     272        } finally { 
     273                rwl.writeLock().unlock(); 
     274        } 
     275 
     276        if (log.isDebugEnabled()) { 
     277                log.debug("lookupPixels for id " + pixelsId + " succeeded: " 
     278                                + this.pixelsObj); 
     279        } 
    275280    } 
    276281 
    … …  
    281286     */ 
    282287    @RolesAllowed("user") 
     288    @Transactional(readOnly = false) 
    283289    public boolean lookupRenderingDef(long pixelsId) { 
    284         rwl.writeLock().lock(); 
    285  
    286         try { 
    287             rendDefObj = pixMetaSrv.retrieveRndSettings(pixelsId); 
    288             closeRenderer(); 
    289             renderer = null; 
    290  
    291             if (rendDefObj == null) { 
    292                 // We've been initialized on a pixels set that has no rendering 
    293                 // definition for the given user. In order to maintain the 
    294                 // proper state and ensure that we avoid transactional problems 
    295                 // we're going to notify the caller instead of performing *any* 
    296                 // magic that would require a database update. 
    297                 // *** Ticket #564 -- Chris Allan <callan@blackcat.ca> *** 
    298                 return false; 
    299             } 
    300         } finally { 
    301             rwl.writeLock().unlock(); 
    302         } 
    303  
    304         if (log.isDebugEnabled()) { 
    305             log.debug("lookupRenderingDef for Pixels=" + pixelsId 
    306                     + " succeeded: " + this.rendDefObj); 
    307         } 
    308         return true; 
     290        rwl.writeLock().lock(); 
     291 
     292        try { 
     293                rendDefObj = pixMetaSrv.retrieveRndSettings(pixelsId); 
     294                closeRenderer(); 
     295                renderer = null; 
     296 
     297                if (rendDefObj == null) { 
     298                        // We've been initialized on a pixels set that has no rendering 
     299                        // definition for the given user. In order to maintain the 
     300                        // proper state and ensure that we avoid transactional problems 
     301                        // we're going to notify the caller instead of performing *any* 
     302                        // magic that would require a database update. 
     303                        // *** Ticket #564 -- Chris Allan <callan@blackcat.ca> *** 
     304                        return false; 
     305                } 
     306        } finally { 
     307                rwl.writeLock().unlock(); 
     308        } 
     309 
     310        if (log.isDebugEnabled()) { 
     311                log.debug("lookupRenderingDef for Pixels=" + pixelsId 
     312                                + " succeeded: " + this.rendDefObj); 
     313        } 
     314        return true; 
    309315    } 
    310316 
    … …  
    318324        rwl.writeLock().lock(); 
    319325 
     326         
    320327        try { 
    321328            errorIfNullPixels(); 
     329             
     330                // Ensure that we do not have "dirty" pixels or rendering settings 
     331            // left around in the Hibernate session cache. 
     332                iQuery.clear(); 
    322333 
    323334            /* 
    … …  
    401412     */ 
    402413    @RolesAllowed("user") 
    403     public int[] renderAsPackedInt(PlaneDef pd) throws ResourceError, 
    404             ValidationException { 
    405         rwl.readLock().lock(); 
    406  
    407         try { 
    408             errorIfInvalidState(); 
    409             return renderer.renderAsPackedInt(pd); 
    410         } catch (IOException e) { 
    411             ResourceError re = new ResourceError("IO error while rendering:\n" 
    412                     + e.getMessage()); 
    413             re.initCause(e); 
    414             throw re; 
    415         } catch (QuantizationException e) { 
    416             InternalException ie = new InternalException( 
    417                     "QuantizationException while rendering:\n" + e.getMessage()); 
    418             ie.initCause(e); 
    419             throw ie; 
    420         } finally { 
    421             rwl.readLock().unlock(); 
    422         } 
     414    public int[] renderAsPackedInt(PlaneDef pd) 
     415        throws ResourceError, ValidationException { 
     416        rwl.writeLock().lock(); 
     417 
     418        try { 
     419                errorIfInvalidState(); 
     420                return renderer.renderAsPackedInt(pd); 
     421        } catch (IOException e) { 
     422                ResourceError re = new ResourceError("IO error while rendering:\n" 
     423                                + e.getMessage()); 
     424                re.initCause(e); 
     425                throw re; 
     426        } catch (QuantizationException e) { 
     427                InternalException ie = new InternalException( 
     428                                "QuantizationException while rendering:\n" + e.getMessage()); 
     429                ie.initCause(e); 
     430                throw ie; 
     431        } finally { 
     432                rwl.writeLock().unlock(); 
     433        } 
    423434    } 
    424435     
    … …  
    481492            // Ensure that we haven't just been called before  
    482493            // lookupRenderingDef(). 
    483             if (rendDefObj == null 
    484                 && pixMetaSrv.retrieveRndSettings(pixelsId) == null) 
     494            if (rendDefObj == null) 
    485495            { 
     496                                RenderingDef def = pixMetaSrv.retrieveRndSettings(pixelsId);  
     497                                if (def != null) 
     498                                { 
     499                                        errorIfInvalidState(); 
     500                                } 
    486501                List<Family> families = 
    487502                        pixMetaSrv.getAllEnumerations(Family.class); 
    … …  
    490505                QuantumFactory quantumFactory = new QuantumFactory(families); 
    491506                        PixelBuffer buffer = pixDataSrv.getPixelBuffer(pixelsObj); 
    492                         RenderingDef def = Renderer.createNewRenderingDef(pixelsObj); 
     507                        def = Renderer.createNewRenderingDef(pixelsObj); 
    493508                        Renderer.resetDefaults(def, pixelsObj, quantumFactory, 
    494509                                               renderingModels, buffer); 
    … …  
    515530            rwl.writeLock().unlock(); 
    516531        } 
    517         iUpdate.flush(); 
    518532    } 
    519533     
    … …  
    573587            errorIfNullRenderingDef(); 
    574588            pixMetaSrv.saveRndSettings(rendDefObj); 
    575         } finally { 
    576             rwl.writeLock().unlock(); 
    577         } 
    578         iUpdate.flush(); 
     589            rendDefObj = reload(rendDefObj); 
     590            iQuery.clear(); 
     591        } finally { 
     592            rwl.writeLock().unlock(); 
     593        } 
    579594    } 
    580595 
    … …  
    11331148    // ========================================================================= 
    11341149 
    1135     protected final static String NULL_RENDERER = "RenderingEngine not ready: renderer is null." 
     1150    protected final static String NULL_RENDERER = "RenderingEngine not ready: renderer is null.\n" 
    11361151            + "This method can only be called " 
    11371152            + "after the renderer is properly " 
    1138             + "initialized (not-null). \n" 
     1153            + "initialized (not-null).\n" 
    11391154            + "Try lookup and/or use methods."; 
    11401155 
    … …  
    11541169 
    11551170    protected void errorIfNullRenderingDef() { 
    1156         if (rendDefObj == null) { 
    1157             throw new ApiUsageException( 
    1158                     "RenderingEngine not ready: RenderingDef object not set."); 
    1159         } 
    1160  
    1161     } 
    1162  
    1163     protected void errorIfNullRenderer() { 
    1164         if (renderer == null) { 
    1165             throw new ApiUsageException(NULL_RENDERER); 
    1166         } 
    1167  
     1171        if (rendDefObj == null) { 
     1172                throw new ApiUsageException( 
     1173                                "RenderingEngine not ready: RenderingDef object not set."); 
     1174        } 
     1175    } 
     1176 
     1177    protected void errorIfNullRenderer() 
     1178    { 
     1179        if (renderer == null && wasPassivated) 
     1180        { 
     1181                load(); 
     1182        } 
     1183        else if (renderer == null) 
     1184        { 
     1185                throw new ApiUsageException(NULL_RENDERER); 
     1186        } 
    11681187    } 
    11691188 
    … …  
    12351254    } 
    12361255 
     1256    /** 
     1257     * Reloads an {@link Pixels} or {@link RenderingDef} object following a 
     1258     * <pre>clear()</pre> being called on the Hibernate session. 
     1259     * @param t The object to reload. 
     1260     * @return A reloaded object of the same type as that passed in. 
     1261     */ 
     1262    @SuppressWarnings("unchecked") 
     1263    private <T extends IObject> T reload(T t) 
     1264    { 
     1265        if (t != null) 
     1266        { 
     1267                if (t instanceof RenderingDef) 
     1268                { 
     1269                        return (T) pixMetaSrv.retrieveRndSettings(pixelsObj.getId()); 
     1270                } 
     1271                else if (t instanceof Pixels) 
     1272                { 
     1273                        return (T) pixMetaSrv.retrievePixDescription(t.getId()); 
     1274                } 
     1275                else 
     1276                { 
     1277                        throw new RuntimeException( 
     1278                                        "Unknown reload class: " + t.getClass()); 
     1279                } 
     1280        } 
     1281        return t; 
     1282    } 
    12371283} 
  • trunk/components/server/src/ome/services/ThumbnailBean.java

    r1949 r1966  
    99 
    1010// Java imports 
    11 import java.awt.Point; 
    1211import java.awt.image.BufferedImage; 
    13 import java.awt.image.ColorModel; 
    14 import java.awt.image.DataBuffer; 
    15 import java.awt.image.DataBufferInt; 
    16 import java.awt.image.DirectColorModel; 
    17 import java.awt.image.SinglePixelPackedSampleModel; 
    18 import java.awt.image.WritableRaster; 
    1912import java.io.ByteArrayOutputStream; 
    2013import java.io.FileOutputStream; 
    … …  
    3629import javax.interceptor.Interceptors; 
    3730 
    38 import ome.api.ICompress; 
     31import ome.api.IPixels; 
    3932import ome.api.IRepositoryInfo; 
    4033import ome.api.IScale; 
    … …  
    4336import ome.api.local.LocalCompress; 
    4437import ome.conditions.ApiUsageException; 
     38import ome.conditions.InternalException; 
    4539import ome.conditions.ResourceError; 
     40import ome.conditions.ValidationException; 
     41import ome.io.nio.PixelBuffer; 
     42import ome.io.nio.PixelsService; 
    4643import ome.io.nio.ThumbnailService; 
    4744import ome.logic.AbstractLevel2Service; 
     45import ome.model.IObject; 
    4846import ome.model.core.Pixels; 
     47import ome.model.display.RenderingDef; 
    4948import ome.model.display.Thumbnail; 
     49import ome.model.enums.Family; 
     50import ome.model.enums.RenderingModel; 
    5051import ome.parameters.Parameters; 
    5152import ome.services.util.OmeroAroundInvoke; 
    … …  
    5354import ome.system.SimpleEventContext; 
    5455import ome.util.ImageUtil; 
    55 import omeis.providers.re.RenderingEngine; 
     56import omeis.providers.re.Renderer; 
    5657import omeis.providers.re.data.PlaneDef; 
     58import omeis.providers.re.quantum.QuantizationException; 
     59import omeis.providers.re.quantum.QuantumFactory; 
    5760 
    5861import org.apache.commons.logging.Log; 
    … …  
    6164import org.jboss.annotation.ejb.RemoteBinding; 
    6265import org.jboss.annotation.ejb.RemoteBindings; 
     66import org.jboss.annotation.ejb.cache.tree.CacheConfig; 
    6367import org.jboss.annotation.security.SecurityDomain; 
    6468import org.springframework.transaction.annotation.Transactional; 
    65  
    66 import sun.awt.image.IntegerInterleavedRaster; 
    6769 
    6870/** 
    … …  
    100102    private transient static Log log = LogFactory.getLog(ThumbnailBean.class); 
    101103 
    102     /** The rendering engine that this service uses for thumbnail creation. */ 
    103     private transient RenderingEngine re; 
    104  
    105     /** The scaling service that will be used to scale buffered images. */ 
     104    /** The renderer that this service uses for thumbnail creation. */ 
     105    private transient Renderer renderer; 
     106 
     107    /** The scaling service will be used to scale buffered images. */ 
    106108    private transient IScale iScale; 
     109     
     110    /** The pixels service, will be used to load pixels and settings. */ 
     111    private transient IPixels iPixels; 
     112     
     113    /** The service used to retrieve the pixels data. */ 
     114    private transient PixelsService pixelDataService; 
    107115 
    108116    /** The ROMIO thumbnail service. */ 
    … …  
    120128    /** The pixels instance that the service is currently working on. */ 
    121129    private Pixels pixels; 
    122  
    123     /** The id of the pixels instance. */ 
    124     private Long pixelsId; 
    125      
    126     /** Only set after a passivated bean is activated. */ 
    127     private transient Long resetPix = null; 
    128  
    129     /** Currently unused. */ 
    130     private transient Long resetRE = null; 
    131      
    132     /** The id of the rendering definition instance. */ 
    133     private Long renderingDefId; 
     130     
     131    /** The rendering settings that the service is currently working with. */ 
     132    private RenderingDef settings; 
    134133 
    135134    /** The default X-width for a thumbnail. */ 
    … …  
    145144    public static final String DEFAULT_MIME_TYPE = "image/jpeg"; 
    146145 
     146    /** Notification that the bean has just returned from passivation. */ 
    Â