Description
HstComponent classes are obviously not thread safe. Thus using
instance variables should take this into account. So assume the code
below:
public class StoreHomePageURLComponent extends BaseHstComponent {
private volatile String homepageURL;
@Override
public void doBeforeRender(final HstRequest request, final
HstResponse response) throws HstComponentException {
if (homepageURL == null) {
synchronized (this) {
if (homepageURL == null)
}
}
request.setAttribute("homepage", homepageURL);
}
}
Do you spot the problem here? Most likely not, as there is not issue
in the code above. However, there is a very big problem with the code
above (which now starts to happen more frequently with cms accessing
site through channelmanager through different host than website
visitors).
The problem is, that only one component instance is created for all
different Mounts that share the same HstComponent (not only class, but
also the location of the hst component configuration). Obviously, we
now need to create less hst component instances when shared, but I
think the problem above it too severe: If I first access the component
above over localhost, the homepageURL for all environments will be
shared as a localhost link.
I think it is more solid if we in
HstComponentWindowFactoryImpl#create(.....)
.......
component = compFactory.getComponentInstance(requestContainerConfig,
compConfig);
......
change it to:
component = compFactory.getComponentInstance(requestContainerConfig,
compConfig, requestContext.getResolvedMount().getMount().getIdentifier());
and include the mount identifier in the componentId in
HstComponentFactoryImpl (code below thus misses the Mount id, and
since HstComponentConfiguration is shared between different mounts on
different hosts environment, we cannot know below which Mount was
used)
public HstComponent getComponentInstance(HstContainerConfig
requestContainerConfig, HstComponentConfiguration compConfig) throws
HstComponentException {
String componentId = compConfig.getId() + compConfig.hashCode();
HstComponent component =
this.componentRegistry.getComponent(requestContainerConfig,
componentId);
If you are ok with my suggestion, I'd like to change the code to
include the Mount identifier in the componentId key for the registry