New posts copied from one web server to another are not visible in the blog

Topics: ASP.NET 2.0
Jan 19, 2009 at 8:24 AM
Hi,

I have a load-balanced setup where there are 2 web servers pointing at the 1 backend database.

For ease of implementation, I only make changes on 1 web server and then synchronise to the other, using SyncBack software.

When I create new posts on the first web server and then synchronise the contents of the Blogenine.Web folder, the new posts are copied over but are not visible on the second web server.

I have to create the new post on the second web server in order to be able to see the post.

Any idea where the issue is? I've checked permissions, IIS settings and compared set up of Blogengine on both web servers but have had no luck.

Thanks in advance,
Gavan
Jan 19, 2009 at 11:26 AM
I would suspect it has to do with caching. I believe you will find similar posts here about what you are attempting with no succes. You would probably need to restart your web app after each sync and I am not sure if that will work either.
Jan 20, 2009 at 5:37 PM
Edited Jan 20, 2009 at 5:38 PM
I just posted a similar question to yours.  The cache is independent on each web server.  I'm trying to find out if it is possible to limit the amount of time the pages/posts are cached, so they stay "close" to in-sync
http://www.codeplex.com/blogengine/Thread/View.aspx?ThreadId=44687
Jan 20, 2009 at 5:51 PM
Provided you are on a server you control you could give BE its own application pool and set it to recycle at some short interval. Of course the downside to this would the first page load after the recycle could be slow. You could alleviate that to a degree with a ping utility or a script that would autoamtically request a page after the recycle.
Coordinator
Jan 20, 2009 at 6:23 PM
One thing you can do to fix the problem with cached posts is to force BE to reload the posts.  I just noticed there's a built-in way to do this with a Reload() static method of the Post class -- which reloads all the posts from the datastore.  It's as simple as:

Post.Reload();

You could run that manually on every hit to your blog -- like on the default.aspx page, or in an extension or httpmodule.  Or design it so the posts are only reloaded after so much time has passed.  Code like the following could be used on your default.aspx page, or in an extension or httpmodule:

int reloadMinuteInterval = 10;
string LastReloadCacheKey = "LastPostReloadTimestamp";
DateTime? lastReloadTime = Cache[LastReloadCacheKey] as DateTime?;

if (!lastReloadTime.HasValue)
{
    lastReloadTime = DateTime.Now;
    Cache[LastReloadCacheKey] = lastReloadTime;
}

TimeSpan timeSinceLastReload = DateTime.Now.Subtract(lastReloadTime.Value);
if (timeSinceLastReload.TotalMinutes > reloadMinuteInterval)
{
    Post.Reload();
    Cache[LastReloadCacheKey] = DateTime.Now;
}
Jan 20, 2009 at 6:27 PM
Ben, I think you need to get out more :) 
(That's my way of thanking you for all the help you have given to others)
Coordinator
Jan 20, 2009 at 6:33 PM
LOL .... you're actually sorta right, I tend to get into things 'excessively', especially once I get familiar with something and know what's going on.  Hello, my name is Ben, and I'm a BlogEngine addict ... help!  :-)
Jan 21, 2009 at 11:38 AM
Thank you BenAmada. Your solution worked a treat.
Mar 4, 2009 at 3:34 PM
Hi, can I get some help implementin the Post.Reload solution?

I tried adding it to the default.aspx and got this error "Parser Error Message: Only Content controls are allowed directly in a content page that contains Content controls."
Mar 4, 2009 at 3:51 PM
Here's the code I use for Page.Reload.  It is in the Page class of BlogEngine.Core:

/// <summary>
        /// Force reload of all posts
        /// </summary>
        public static void Reload()
        {
            lock (_SyncRoot)
            {
                _Pages = BlogService.FillPages();
                _Pages.Sort(delegate(Page p1, Page p2) { return String.Compare(p1.Title, p2.Title); });
            }
        }
Coordinator
Mar 4, 2009 at 4:24 PM
lewiska: If you were to try and implement that code I posted back on January 20th, there's several places it could go.  If you were trying to put it in the default.aspx file, then you would actually need to put it in the default.aspx.cs file.  The code could be placed in the beginning of the Page_Load event.  For example:

protected void Page_Load(object sender, EventArgs e)
{
    if (Page.IsCallback)
        return;

    int reloadMinuteInterval = 10;
    string LastReloadCacheKey = "LastPostReloadTimestamp";
    DateTime? lastReloadTime = Cache[LastReloadCacheKey] as DateTime?;

    if (!lastReloadTime.HasValue)
    {
        lastReloadTime = DateTime.Now;
        Cache[LastReloadCacheKey] = lastReloadTime;
    }

    TimeSpan timeSinceLastReload = DateTime.Now.Subtract(lastReloadTime.Value);
    if (timeSinceLastReload.TotalMinutes > reloadMinuteInterval)
    {
        Post.Reload();
        Cache[LastReloadCacheKey] = DateTime.Now;
    }
    
    .... EXISTING STUFF ....        
}
Mar 4, 2009 at 5:39 PM
Many thanks guys! BenAmada's default.aspx.cs solution seems to work for me  ...
Apr 22, 2010 at 2:20 PM
Edited Apr 22, 2010 at 2:20 PM

Just started using BlogEngine and it is pretty good, but I too am having a lot of issues on the web farm.  So, I've posted some info on some ideas I've been experimenting with here:

http://aewnet.com/post/2010/04/21/BlogEngineNET-and-a-Webfarm.aspx

Ben's code above works great for Posts, so I've added some additional reloads to some other sections and tweaked some code in the settings to make some other areas get the data across the farm when it's posted.  Hope this help.