ned Productions Ltd News
News regarding ned Productions Ltd services and products
Feb 18, 2010
Upgrade to Plone v3.3.4 will happen tomorrow
We would like to announce that the upgrade of Plone to v3.3.4 will occur between tomorrow (Friday 19th Feb) and the end of this weekend (Sun 21st Feb). After this upgrade, for each of your websites you will need to do the following:
- Enter portal_migration in your ZMI and upgrade.
- Enter portal_quickinstaller in your ZMI and reinstall any products which have been upgraded. We strongly recommend that you do one at a time if you get any errors by trying to do all at once.
- For each product upgraded, reenter its settings in Site Setup. For example TinyMCE will return to default settings.
During the upgrade your website will still be present, but any attempts to login may return a 502 Service Unavailable error. In the highly unlikely situation that your site dies after the upgrade, please contact us.
Details behind the upgrade:
We have been waiting for v2.0.5 of the varnish web cache to be released before we performed the upgrade of our Plone installation to v3.3.4. This is because that release of varnish finally adds support for the HTTP If-None-Match header which is used by web browsers on Plone sites to tell the web server which version of a web page they already have a copy of by sending its last known ETag. Unfortunately, varnish used to always bypass its cache when it saw such a header which effectively meant that all visitors to any ned Productions Ltd. website who had been here before bypassed the cache (not that this caused much load nor delay, as Zope simply returned a 304 Not Modified).
What that meant in practice was that if we took down Plone for any reason, every visitor who had been before instantly got a 502 Service Unavailable error. Other than stripping If-None-Match support and therefore greatly increasing page load times while visitors navigated our sites, there wasn't much we could do.
With this new support however, we can now take down Plone for up to 24h and varnish will continue to serve out its cached content and so long as the cache has a copy of the page, no one should notice a thing. Obviously enough because logged in users always bypass the cache they will not be able to log in at all during the upgrade. Right now the cache is being populated, so we should be ready to start work tomorrow.
Obviously enough this new feature considerably improves load scalability and load times of changed pages on all ned Productions Ltd. websites. Whereas before Zope always had to be asked to verify an ETag and if it didn't match then Zope had to deliver a copy of the page, now varnish understands ETags and will handle everything. This should reduce page load times for updated pages by a few hundred milliseconds.
Other new features resulting from this upgrade are mostly bug fixes. Firefox users will see a very substantial improvement in page load times as a bug invoking Java with every page has been fixed. There has been a very rare XSS vulnerability fixed in Zope (not an issue in Plone), and there have been many more bug fixes to TinyMCE and a few other components.
Feb 01, 2010
Added Geo-Direction and Wiki
We finally got around to implementing the geo-directing part of the ned Productions Ltd web services platform, so finally all our hosted websites are now being served to their closest geographical server. This has very substantially improved page load times and browsing speeds for our customers:

Our server locations are as follows:
We have also added a new product: you can now have your own sites be geo-directed for a low low price of just €12/year!
We strongly believe in being transparent about how we implement our products and services so you can see for yourself their quality - or indeed, how to implement them yourselves if you so chose. We have hence opened a new Wiki section which contains detailed implementation notes as a public service.
Nov 09, 2009
Implementing typeof() in Microsoft's C++ compiler
While most compilers implement the C99 feature typeof(), unfortunately the Microsoft C++ compiler does not as yet. Here's an implementation which can be just dropped in:
#if defined(_MSC_VER) && _MSC_VER>=1400
namespace msvc_typeof_impl {
/* This is a fusion of Igor Chesnokov's method (http://rsdn.ru/forum/src/1094305.aspx)
and Steven Watanabe's method (http://lists.boost.org/Archives/boost/2006/12/115006.php)
How it works:
C++ allows template type inference for templated function parameters but nothing else.
What we do is to pass the expression sent to typeof() into the templated function vartypeID()
as its parameter, thus extracting its type. The big problem traditionally now is how to get
that type out of the vartypeID() instance, and here's how we do it:
1. unique_type_id() returns a monotonically increasing integer for every unique type
passed to it during this compilation unit. It also specialises an instance of
msvc_extract_type<unique_type_id, type>::id2type_impl<true>.
2. vartypeID() returns a sized<unique_type_id> for the type where
sizeof(sized<unique_type_id>)==unique_type_id. We vector through sized as a means
of returning the unique_type_id at compile time rather than runtime.
3. msvc_extract_type<unique_type_id> then extracts the type by using a bug in MSVC to
reselect the specialised child type (id2type_impl<true>) from within the specialisation
of itself originally performed by the above instance of unique_type_id. This bug works
because when MSVC calculated the signature of the specialised
msvc_extract_type<unique_type_id, type>::id2type_impl<true>, it does not include the
value of type in the signature of id2type_impl<true>. Therefore when we reselect
msvc_extract_type<unique_type_id>::id2type_impl<true> it erroneously returns the one
already in its list of instantiated types rather than correctly generating a newly
specialised msvc_extract_type<unique_type_id, msvc_extract_type_default_param>::id2type_impl<true>
This bug allows the impossible and gives us a working typeof() in MSVC. Hopefully Microsoft
won't fix this bug until they implement a native typeof.
*/
struct msvc_extract_type_default_param {};
template<int ID, typename T = msvc_extract_type_default_param> struct msvc_extract_type;
template<int ID> struct msvc_extract_type<ID, msvc_extract_type_default_param>
{
template<bool> struct id2type_impl;
typedef id2type_impl<true> id2type;
};
template<int ID, typename T> struct msvc_extract_type : msvc_extract_type<ID, msvc_extract_type_default_param>
{
template<> struct id2type_impl<true> //VC8.0 specific bugfeature
{
typedef T type;
};
template<bool> struct id2type_impl;
typedef id2type_impl<true> id2type;
};
template<int N> class CCounter;
// TUnused is required to force compiler to recompile CCountOf class
template<typename TUnused, int NTested = 0> struct CCountOf
{
enum
{
__if_exists(CCounter<NTested>) { count = CCountOf<TUnused, NTested + 1>::count }
__if_not_exists(CCounter<NTested>) { count = NTested }
};
};
template<class TTypeReg, class TUnused, int NValue> struct CProvideCounterValue { enum { value = NValue }; };
// type_id
#define unique_type_id(type) \
(CProvideCounterValue< \
/*register TYPE--ID*/ typename msvc_extract_type<CCountOf<type >::count, type>::id2type, \
/*increment compile-time Counter*/ CCounter<CCountOf<type >::count>, \
/*pass value of Counter*/CCountOf<type >::count \
>::value)
// Lets type_id() be > than 0
class __Increment_type_id { enum { value = unique_type_id(__Increment_type_id) }; };
// vartypeID() returns a type with sizeof(type_id)
template<int NSize> class sized { char m_pad[NSize]; };
template<typename T> typename sized<unique_type_id(T)> vartypeID(T&);
template<typename T> typename sized<unique_type_id(const T)> vartypeID(const T&);
template<typename T> typename sized<unique_type_id(volatile T)> vartypeID(volatile T&);
template<typename T> typename sized<unique_type_id(const volatile T)> vartypeID(const volatile T&);
}
#define typeof(expression) msvc_typeof_impl::msvc_extract_type<sizeof(msvc_typeof_impl::vartypeID(expression))>::id2type::type
#endif
I hope you find this useful. For this and loads more useful C++ stuff, try the Boost libraries or my own TnFOX portability toolkit.
