[ 
https://issues.apache.org/jira/browse/FELIX-3422?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14052422#comment-14052422
 ] 

Denis Rossi commented on FELIX-3422:
------------------------------------

I found that LocalRepositoryImpl is registering itself as AllServiceListener.
In the serviceChanged method the m_snapshotTimeStamp, that is used by 
getLastModified() method,  is updated and the bundle is removed and re-added:

 public void serviceChanged(ServiceEvent event)
    {
        Bundle bundle = event.getServiceReference().getBundle();
        if (bundle.getState() == Bundle.ACTIVE && event.getType() != 
ServiceEvent.MODIFIED)
        {
            synchronized (this)
            {
                removeBundle(bundle, m_logger);
                addBundle(bundle, m_logger);
                m_snapshotTimeStamp = System.currentTimeMillis();
            }
        }
    }


> Improve framework state change checking in ResolverImpl.deploy()
> ----------------------------------------------------------------
>
>                 Key: FELIX-3422
>                 URL: https://issues.apache.org/jira/browse/FELIX-3422
>             Project: Felix
>          Issue Type: Improvement
>          Components: Bundle Repository (OBR)
>    Affects Versions: bundlerepository-1.6.6
>         Environment: All platforms
>            Reporter: Declan Cox
>            Priority: Minor
>              Labels: patch
>
> Currently the ResolverImpl deploy method checks to see if the last modified 
> time of a repository instance is greater than the last updated resolution 
> start timestamp, indicating a possible inconsistent state between the 
> repository resources and the set of resolved resources. However it appears 
> that the last modified time on a repository instance can be updated by the 
> framework without it affecting the resolve state of the contained resources. 
> The following comment indicates that the original implementer is aware of 
> this, viz:
>         // Check to make sure that our local state cache is up-to-date
>         // and error if it is not. This is not completely safe, because
>         // the state can still change during the operation, but we will
>         // be optimistic. This could also be made smarter so that it checks
>         // to see if the local state changes overlap with the resolver.
>         for (int repoIdx = 0; (m_repositories != null) && (repoIdx < 
> m_repositories.length); repoIdx++)
>         {
>             if (m_repositories[repoIdx].getLastModified() > 
> m_resolveTimeStamp)
>             {
>                 throw new IllegalStateException("Framework state has changed, 
> must resolve again.");
>             }
>         }
> I have encountered this error on an upgrade from version 1.0.3 to 1.6.6 
> recently (we have a provisioning agent which delegates to the bundle 
> repository ). What we have seen is that between a call to resolve() and 
> deploy() the local repository last modified timestamp is updated, however on 
> investigation all contained resources have been resolved but we get the 
> IllegalStateException nonetheless. 
> We are not sure why this update happens and where it comes from (this we will 
> investigate further), however we could avoid the unnecessary exception by 
> checking the overlap with the resolved set as suggested above. 
> To this end I added the following private method to ResolverImpl in a local 
> copy, which seems to do the trick:
>       /**
>      * Check to see if the repository state has changed and whether
>      * this state change requires re-resolving
>      *
>      * @param repository - repository instance
>      * @return true if state has changed requiring re-resolving, otherwise 
> false
>      */
>     private boolean hasStateChanged(final Repository repository) {
>         if (repository.getLastModified() > m_resolveTimeStamp.get()) {
>             // check overlap with resolver
>             final Resource[] resources = repository.getResources();
>             for (int i = 0; i < resources.length; i++) {
>                 if (!m_resolveSet.contains(resources[i])) {
>                     return true;
>                 }
>             }
>         }
>         return false;
>     }
> The corresponding change to the deploy method is as follows:
>         // Check to make sure that our local state cache is up-to-date
>         // and error if it is not. This is not completely safe, because
>         // the state can still change during the operation, but we will
>         // be optimistic. This could also be made smarter so that it checks
>         // to see if the local state changes overlap with the resolver.
>         for (int repoIdx = 0; (m_repositories != null) && (repoIdx < 
> m_repositories.length); repoIdx++)
>         {
>             final Repository repository = m_repositories[repoIdx];
>             if (hasStateChanged(repository))
>             {
>                 throw new IllegalStateException("Framework state has changed, 
> must resolve again.");
>             }
>         }
> I am not sure if this is the most efficient way to do this and if all 
> considerations about state change have been taken into account (I am new to 
> Felix) but I thought would submit it for consideration as a potential patch. 
> Thanks,
> Declan



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to