Wednesday, April 11, 2012

Making GSP so easy to install no one will pay the $100 install fee

For the longest time I have offered to install GSP with your requested settings for $100. I still do and will continue to do so. But for anyone with a few minutes, it is actually quite easy to install on your own. The Admin Guide has step by step directions for some of the common ways to install the gallery. Today I added one more – how to install the gallery when a web host supports the Microsoft Web Application Gallery (WAG).

To the unfamiliar, the WAG is a collection of open source web applications that can be easily installed.  This scenario is really the easiest way to get a gallery up and running when you know next to nothing about running a web site. All you need to do is create an account with a hosting company and click a couple of next…next links in a wizard. Two minutes later your gallery is ready to go.

There is a new HOW-TO in the Admin Guide called How-To: Install using Microsoft Web Application Gallery on a web host. It shows the process for installing a new gallery at Arvixe. The rest of this blog post is copied from there.

How-To: Install using Microsoft Web Application Gallery on a web host

Some web hosting companies integrate the Microsoft Web Application Gallery (WAG) into their control panel. When available, this is often the easiest way to set up a gallery as it requires minimal technical skills. This is a walkthrough for installing Gallery Server Pro on a new web site at Arvixe through WAG.
  1. Ensure your site is running .NET 4.0 or higher in Integrated Mode. At Arvixe, log in to the Control Panel and click Web Sites in the Hosting Space Menu on the left. Then click the name of your website from the list, as seen here:

    arvixe_websites
  2. The Web Site Properties page appears. Click the Extensions tab and verify your site is running ASP.NET 4.0 (Integrated):

    asp_net_integrated
  3. Click Microsoft Web App Gallery in the Hosting Space Menu and filter the list by the Galleries category. Find Gallery Server Pro in the list and click Install.

    arvixe_gsp1
  4. The Download Web Application dialog appears. Click Next.

    arvixe_gsp2
  5. Fill out the requested fields and click Install.

    arvixe_gsp3
  6. After it is installed a confirmation message appears.

    arvixe_gsp4
  7. That’s it! Click Launch Gallery Server Pro to see your new gallery.

    arvixe_gsp5

Spanish version of 2.6.1 available

A volunteer has created a Spanish translation of 2.6.1. Enjoy!

Thursday, March 1, 2012

Video and audio in Win8/IE10 Metro

Yesterday Microsoft released the Windows 8 Consumer Preview (beta), so I downloaded it and installed it on my laptop. One of the first things I did was use the new Metro interface to look at how Gallery Server Pro looked in Internet Explorer 10. Overall, things looked great until I tried to view one of the videos in the demo gallery:

IE_metro_mp4_with_flash_cropped

That really wasn’t a surprise since the browser templates in GSP are configured to use either Flash or Silverlight for video and audio in IE. However, Microsoft has decided not to support any plug-ins in IE10 when running in Metro. (Plug-ins *are* supported when IE is running in desktop mode.) Instead, Microsoft is encouraging use of native HTML5 <video> and <audio> tags for media. That is great, except out of the box IE only supports H.264 (MP4) for video and MP3/AAC for audio. Any other video or audio format, such as your collection of Flash Video files (FLV), are simply not going to work in IE10 Metro. Period.

As drastic as this seems, I welcome the move away from plug-ins, as I can’t tell you how many hours I have spent fiddling with Flash/FlowPlayer/QuickTime/DIVX/Silverlight scripts and configurations over the years. That has easily been the most difficult challenge with GSP – how to best render any type of file (video, audio, document, image, etc) in any kind of browser.

A plug-in free world, however, brings a different kind of mess. Different browsers support different video and audio codecs, and there isn’t a single format that works in all browsers. But I digress.

Let’s get back to IE10 Metro in Win8. Since IE10 supports H.264 (MP4), we can tweak the browser template so that newer versions of IE that support MP4 get the HTML5 <video> tag, while older versions (before IE9) continue to use Flash. To make this change, run the following SQL scripts against your Gallery Server Pro database:

INSERT INTO [gs_BrowserTemplate] ([MimeType],[BrowserId],[HtmlTemplate],[ScriptTemplate]) VALUES (N'video/mp4',N'ie1to8',N'<a href="{MediaObjectUrl}" style="display:block;width:{Width}px;height:{Height}px" id="gsp_player"></a>',N'window.gspRunFlowPlayer=function(){jQuery("#gsp_player").attr("href",function(){return this.href.replace(/&/g,"%26")});flowplayer("gsp_player",{src:"{GalleryPath}/script/flowplayer-3.2.7.swf",wmode:"opaque"},{clip:{autoPlay:{AutoStartMediaObjectText},scaling:"fit"}})};if(window.flowplayer){gspRunFlowPlayer()}else{jQuery.getScript("{GalleryPath}/script/flowplayer-3.2.6.min.js",gspRunFlowPlayer)};');
GO

INSERT INTO [gs_BrowserTemplate] ([MimeType],[BrowserId],[HtmlTemplate],[ScriptTemplate]) VALUES (N'video/mp4',N'ie',N'<video src="{MediaObjectUrl}" controls autobuffer {AutoPlay}><p>Cannot play: Your browser does not support the <code>video</code> element or the codec of this file. Use another browser or download the file by clicking the download toolbar button above (available only when downloading is enabled).</p></video',N'');
GO

This SQL works against GSP 2.6.0 or higher. Older versions use a different version of FlowPlayer so you’ll have to adjust the script accordingly.

After adding these rows, restart the IIS application pool to clear the cache. When refreshing the page above, it now looks like this:

IE_metro_mp4_with_html5_cropped

That’s better. The built-in video controls offer basic playback features like play and pause, but unfortunately it is missing a full-screen mode. Hopefully Microsoft includes it in the final IE10 release.

This solves the issue of rendering H.264 (MP4) videos. A similar SQL script can be used for handling MP3/AAC audio (sorry, but I don’t have time to put that one together). But how to handle other video and audio types? Unfortunately, I know of no way to get other types to work in IE10 Metro. The good news is that you can still see this content in Win8; you just have to move over to desktop mode first. Microsoft is well aware that tons of plug-in dependent sites will break in IE10 Metro and has added a button on the screen to easily switch to desktop mode for the current page.

Should you run this SQL script against your current gallery? Probably not. All it does is make it possible to view MP4 video in IE10 Metro. Other IE10 scenarios, such as Win8’s desktop mode and IE10 on Vista/Win7 already work just fine (as long as Flash is installed). And there is even a slight downside in that IE9 users will now use the HTML5 video player, which is not as nice as the Flash one (e.g. it is missing a full-screen button).

I will likely incorporate the browser template changes described in this post in the next version of GSP. And I will continue to monitor the current state of all browsers and their video/audio support so that GSP takes advantage of their latest capabilities while working in as many older browsers as possible.

Friday, February 17, 2012

Version 2.6.1 released

Gallery Server Pro 2.6.1 is now available. It contains a handful of bug fixes and – for those using the SQL CE database engine – up to 50% faster synchronization performance. My previous blog post details the performance enhancements.

Upgrading your gallery from 2.5 or 2.6.0 is as easy as copying the files from the upgrade package over your existing files (always do a backup first!). If upgrading from an earlier version or using the DotNetNuke module, refer to the Admin Guide.

The bug fixes in 2.6.1 are shown below. More details can be found in the 2.6.1 Defects Report.

  • A COMException may be thrown when adding an image or performing a synchronization.
  • An IOException may be thrown when adding an image or performing a synchronization.
  • Page may hang during file upload.
  • Profile settings for users do not always reflect the most current data.
  • The server's memory cache is not cleared after uploading media files.
  • Confirmation message may not appear when validating new user account.
  • Moving an album to another gallery causes BusinessException when subsequently
    viewing target gallery.
  • (DotNetNuke) Cannot restore backup file.
  • Error "Maximum request length exceeded" during file upload.
  • IIS worker process crashes when editing role on Manage Roles page.

Thursday, February 16, 2012

SQL CE performance improvements in 2.6.1

Galleries using SQL CE benefited from significant performance improvements in 2.6.0. Retrieval of data was up to 15 times faster than in 2.5. However, many users noticed that synchronize operations still were slower than both SQL Server and the now obsolete SQLite data provider (replaced by SQL CE in 2.5). This week I focused on analyzing the source of the difference with an aim to improve it. I am pleased to say that I succeeded in achieving about a 50% speed improvement with only a minimal change. I will soon be releasing 2.6.1, which contains this benefit as well as several bug fixes.

Before I dig into the details, I want to mention that the upcoming .NET 4.5 runtime is expected to bring additional performance benefits to SQL CE users. The ADO.NET Team just announced some details that show a real world app running 67% faster under .NET 4.5 than .NET 4.0. This will be in addition to the performance enhancements in 2.6.1, so there is a lot of movement in the SQL CE performance arena.

What is taking so long?

Using the Performance Analyzer in Visual Studio 2010, I ran some tests against Gallery Server Pro 2.6.0 using both the SQL CE and SQL Server data providers. I studied gigabytes of data and was able to condense it all down to these two tables:

Table A - 2.6.0, Sync 648 images

 

SQL CE

SQL Server

Duration

38.3 min.

13 min.

% of time inserting records into gs_MediaObjectMetadata

41%

0.21%

Table B - 2.6.0, Sync existing 105 images, option ‘Re-import metadata’ selected (no thumbnail or optimized images created)

 

SQL CE

SQL Server

Duration

9.3 min.

1.6 min.

% of time inserting records into gs_MediaObjectMetadata

83%

4.4%

Table A shows the performance when the sync operation discovers and finds 648 new objects. This requires creating thumbnail and optimized images.

Table B shows a sync of an album that already has 105 images in the gallery. The option ‘Re-import metadata’ is selected, resulting in a sync where all it is really doing is extracting and inserting metadata, since no thumbnail/optimized images need to be created.

Notice that for the first test, SQL CE takes nearly three times longer than SQL Server, with almost half the time spent inserting records into gs_MediaObjectMetadata. This table stores data such as camera model, shutter speed, file size, etc. Each media object in the gallery usually has at least four metadata records, and there are often twenty or thirty for images from digital cameras. In the tests above each image had about 20 metadata items.

Table B shows an even more dramatic difference. When we remove the time-consuming image generation from a sync, more than 80% of the time is spent inserting metadata records in SQL CE, while it is only 4.4% in SQL Server.

It was pretty clear I needed to focus on the metadata insertion routine. Here is the SQL CE version:

InsertMetadataItems260

It loops through each metadata item, converts it into a simple data object, and passes it to the Entity Framework (EF) data context for persisting to the database. Digging into the data further, I could see that nearly all the time in this function was spent executing ctx.SaveChanges().

Ah ha! The villain hath made himself known! SaveChanges is an Entity Framework/.NET method that does a lot of complicated stuff to ensure data integrity. It has been an incredible productivity booster for developers, but it can be much slower than pure ADO.NET. And here we have a perfect example.

Look at the SQL SaveChanges() generates:

insert [gs_MediaObjectMetadata]
([FKMediaObjectId], [MetadataNameIdentifier], [Description], [Value]) values (@0, @1, @2, @3)

select [MediaObjectMetadataId]
from [gs_MediaObjectMetadata]
where [MediaObjectMetadataId] = @@IDENTITY

The first one I expected. The second one made me cringe. It forces SQL CE to query the table to look for the newly assigned ID, when it could avoid the table search by just doing this:

SELECT @@IDENTITY()

Since the inefficient SQL was executing for each metadata insertion, a media object with 20 metadata properties was causing a SELECT query against the table 20 times. In contrast, the SQL Server routine executes a stored procedure where the newly assigned ID is returned as an output parameter, and no SELECT is used.

A few failed attempts

Using the hypothesis that the unnecessary table search after every insert was the root cause, I spent some time looking for a setting or some way to optimize the SQL. In the end, I couldn’t find one. There seemed to be no way to tell EF that there was a better way to do things.

It is well known that the fastest way to interact with data in the .NET world is to use ADO.NET. Although I used EF in the SQL CE data provider, there is no technical reason why I couldn’t replace the EF approach in one place with blazing fast ADO.NET. So I whipped up a replacement function for inserting metadata:

InsertMetadataItems_ADONET

This change made an incredible difference. Repeating the test from Table A showed that the percent of time spent inserting metadata dropped from 41% to 0.91%. By changing one function, suddenly SQL CE was performing within spitting distance of SQL Server.

But then something horrible happened. Before the test finished, the IIS worker process w3wp.exe crashed. It experienced an AccessViolationException with the message ‘Attempted to read or write protected memory. This is often an indication that other memory is corrupt’.

I did some more tests, and the error happened at some random point in every sync I ran. At one point I was able to capture a stack trace:

at System.Data.SqlServerCe.SqlCeConnection.Dispose(Boolean disposing)
at System.ComponentModel.Component.Dispose()
at System.Data.Entity.Internal.LazyInternalConnection.Dispose()
at System.Data.Entity.Internal.LazyInternalContext.DisposeContext()
at System.Data.Entity.Internal.InternalContext.Dispose()
at System.Data.Entity.DbContext.Dispose()
at GalleryServerPro.Data.SqlCe.SqlCeGalleryServerProProvider.MediaObject_Save(IGalleryObject mediaObject) in C:\Dev\GSP\Dev-Main-2.5\Src\TIS.GSP.Data.SqlCE\SqlCeGalleryServerProProvider.cs:line 828
at GalleryServerPro.Business.MediaObjectSaveBehavior.Save() in C:\Dev\GSP\Dev-Main-2.5\Src\TIS.GSP.Business\MediaObjectSaveBehavior.cs:line 82
at GalleryServerPro.Business.GalleryObject.Save() in C:\Dev\GSP\Dev-Main-2.5\Src\TIS.GSP.Business\GalleryObject.cs:line 959
at GalleryServerPro.Business.SynchronizationManager.UpdateExistingMediaObject(IAlbum album, IGalleryObject mediaObject) in C:\Dev\GSP\Dev-Main-2.5\Src\TIS.GSP.Business\SynchronizationManager.cs:line 707
at GalleryServerPro.Business.SynchronizationManager.SynchronizeMediaObjectFiles(DirectoryInfo directory, IAlbum album) in C:\Dev\GSP\Dev-Main-2.5\Src\TIS.GSP.Business\SynchronizationManager.cs:line 614
at GalleryServerPro.Business.SynchronizationManager.Synchronize(String synchId, IAlbum album, String userName) in C:\Dev\GSP\Dev-Main-2.5\Src\TIS.GSP.Business\SynchronizationManager.cs:line 207
at Gsp.Gallery.Synchronize(Int32 albumId, String synchId, Boolean isRecursive, Boolean rebuildThumbnails, Boolean rebuildOptimized, Boolean regenerateMetadata) in C:\Dev\GSP\Dev-Main-2.5\Src\Website\gs\services\Gallery.asmx.cs:line 549

The error was occurring within EF code, not the new ADO.NET code I just wrote. For some reason, combining EF and ADO.NET together was not working. I googled around but ultimately found nothing. I racked my brain for a couple hours trying to figure out some way to preserve this awesome new performance trick, but in the end I could not solve it.

I had to scrap the ADO.NET code. With a sniff and a tear in my eye I hit the delete key…

The solution that worked

I went back to the original InsertMetadataItems() function and studied it. What if, instead of calling SaveChanges() for each metadata insertion, I batched them up and only ran it once for each media object? I commented out the SaveChanges() line and the one immediately after it (since we no longer would have the newly assigned ID at that point) and ran the test again.

Success! The time it took to run the tests dropped by almost half! Here is the data from table B again, this time with an additional column for the improved version.

Table C - Sync existing 105 images, option ‘Re-import metadata’ selected (no thumbnail or optimized images created)

 

SQL CE
2.6.0

SQL CE
2.6.1

SQL Server

Duration

9.3 min.

4.8 min.

1.6 min.

% of time inserting records into gs_MediaObjectMetadata

83%

72%

4.4%

# of calls to SaveChanges()

2404

108

N/A

Interestingly, the SQL generated by EF still includes the unnecessary table query, which may account for much of the remaining performance difference with SQL Server. But reducing the number of calls to SaveChanges() still had a dramatic effect.

In order to preserve the original behavior of the function, I wasn’t done yet. I still needed to assign the newly created ID to the metadata objects. So I added a little plumbing code to assign all the IDs once they are known. Here is the final version of the function:

InsertMetadataItems261

Wrap up

This change really improves insertion scenarios in SQL CE, which are primarily synchronizations and file uploads to the gallery. Retrieval performance is already pretty good.

Even with this change and the expected improvements in .NET 4.5, SQL Server will remain the fastest data provider for Gallery Server Pro. It is highly optimized to use stored procedures, indexes, and carefully constructed ADO.NET.

Use SQL Server when you need the best performance and don’t mind it’s additional complexity and maintenance requirements. Use SQL CE when simplicity is paramount.

Monday, December 12, 2011

Slow e-mail on forum fixed

For the last couple of months, e-mails sent from the forum have taken many hours to arrive. This was particularly frustrating to new users who want to ask a question and have to wait until the next day for their verification e-mail to arrive, but it also delayed my ability to get notified that a new post needed attention.

Last week I was able to dig into this. Initially I suspected the web hosting company had an overloaded e-mail server, so I submitted a help desk ticket with them. They couldn’t find any issues on their end, so I started looking at the source code of the open source forum software YetAnotherForum.NET. Eventually I tracked down an issue with their code, which I was able to work around by clearing out one of the database tables that held e-mails waiting to get sent. I submitted an issue with their bug tracker, so hopefully they’ll be able to resolve it.

E-mails seem to be instantaneous again, so I think we are back in business. I offer my apologies for any inconvenience this has caused.

Wednesday, November 9, 2011

WPI version of Gallery Server Pro 2.6.0 released

Microsoft has completed their testing of 2.6.0 and published the new version to their web application gallery. A link to install it is on the download page.