fixed ninjet's race condition

This commit is contained in:
Keivan 2010-10-10 12:00:07 -07:00
parent b112e28b80
commit 30d38eead6
11 changed files with 259 additions and 63 deletions

View File

@ -7,6 +7,7 @@ using NLog.Targets;
using NzbDrone.Core.Entities; using NzbDrone.Core.Entities;
using NzbDrone.Core.Entities.Episode; using NzbDrone.Core.Entities.Episode;
using NzbDrone.Core.Providers; using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Fakes;
using SubSonic.DataProviders; using SubSonic.DataProviders;
using SubSonic.Repository; using SubSonic.Repository;
using NLog; using NLog;
@ -15,24 +16,33 @@ namespace NzbDrone.Core
{ {
public static class CentralDispatch public static class CentralDispatch
{ {
private static IKernel _kernel;
private static readonly Object kernelLock = new object();
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public static void BindKernel(IKernel kernel) public static void BindKernel()
{ {
lock (kernelLock)
{
Logger.Debug("Binding Ninject's Kernel");
_kernel = new StandardKernel();
string connectionString = String.Format("Data Source={0};Version=3;", Path.Combine(AppPath, "nzbdrone.db")); string connectionString = String.Format("Data Source={0};Version=3;", Path.Combine(AppPath, "nzbdrone.db"));
var provider = ProviderFactory.GetProvider(connectionString, "System.Data.SQLite"); var provider = ProviderFactory.GetProvider(connectionString, "System.Data.SQLite");
provider.Log = new SonicTrace(); provider.Log = new SonicTrace();
provider.LogParams = true; provider.LogParams = true;
kernel.Bind<ISeriesProvider>().To<SeriesProvider>().InSingletonScope(); _kernel.Bind<ISeriesProvider>().To<SeriesProvider>().InSingletonScope();
kernel.Bind<ISeasonProvider>().To<SeasonProvider>(); _kernel.Bind<ISeasonProvider>().To<SeasonProvider>();
kernel.Bind<IEpisodeProvider>().To<EpisodeProvider>(); _kernel.Bind<IEpisodeProvider>().To<EpisodeProvider>();
kernel.Bind<IDiskProvider>().To<DiskProvider>(); _kernel.Bind<IDiskProvider>().To<DiskProvider>();
kernel.Bind<ITvDbProvider>().To<TvDbProvider>(); _kernel.Bind<ITvDbProvider>().To<TvDbProvider>();
kernel.Bind<IConfigProvider>().To<ConfigProvider>().InSingletonScope(); _kernel.Bind<IConfigProvider>().To<ConfigProvider>().InSingletonScope();
kernel.Bind<INotificationProvider>().To<NotificationProvider>().InSingletonScope(); _kernel.Bind<INotificationProvider>().To<FakeNotificationProvider>().InSingletonScope();
kernel.Bind<IRepository>().ToMethod(c => new SimpleRepository(provider, SimpleRepositoryOptions.RunMigrations)).InSingletonScope(); _kernel.Bind<IRepository>().ToMethod(c => new SimpleRepository(provider, SimpleRepositoryOptions.RunMigrations)).InSingletonScope();
ForceMigration(kernel.Get<IRepository>()); ForceMigration(_kernel.Get<IRepository>());
}
} }
public static String AppPath public static String AppPath
@ -48,6 +58,19 @@ namespace NzbDrone.Core
} }
public static IKernel NinjectKernel
{
get
{
if (_kernel == null)
{
BindKernel();
}
return _kernel;
}
}
public static void ConfigureNlog() public static void ConfigureNlog()
{ {

View File

@ -149,6 +149,7 @@
<Compile Include="Entities\Notification\BasicNotification.cs" /> <Compile Include="Entities\Notification\BasicNotification.cs" />
<Compile Include="Entities\Notification\NotificationStatus.cs" /> <Compile Include="Entities\Notification\NotificationStatus.cs" />
<Compile Include="Entities\Notification\NotificationType.cs" /> <Compile Include="Entities\Notification\NotificationType.cs" />
<Compile Include="Providers\Fakes\FakeNotificationProvider.cs" />
<Compile Include="Providers\INotificationProvider.cs" /> <Compile Include="Providers\INotificationProvider.cs" />
<Compile Include="Providers\IMediaDiscoveryProvider.cs" /> <Compile Include="Providers\IMediaDiscoveryProvider.cs" />
<Compile Include="Providers\IMediaProvider.cs" /> <Compile Include="Providers\IMediaProvider.cs" />

View File

@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using NzbDrone.Core.Entities.Notification;
namespace NzbDrone.Core.Providers.Fakes
{
class FakeNotificationProvider : INotificationProvider
{
private readonly Dictionary<Guid, BasicNotification> _basicNotifications = new Dictionary<Guid, BasicNotification>();
private readonly Dictionary<Guid, ProgressNotification> _progressNotification = new Dictionary<Guid, ProgressNotification>();
private readonly Object _lock = new object();
ProgressNotification fakeNotification = new ProgressNotification("Updating Series");
public void Register(ProgressNotification notification)
{
_progressNotification.Add(notification.Id, notification);
}
public void Register(BasicNotification notification)
{
_basicNotifications.Add(notification.Id, notification);
}
public List<BasicNotification> BasicNotifications
{
get { return new List<BasicNotification>(_basicNotifications.Values); }
}
public List<ProgressNotification> ProgressNotifications
{
get
{
fakeNotification.Status = NotificationStatus.InProgress;
fakeNotification.CurrentStatus = DateTime.Now.ToString();
return new List<ProgressNotification> { fakeNotification };
}
}
public void Dismiss(Guid notificationId)
{
lock (_lock)
{
if (_basicNotifications.ContainsKey(notificationId))
{
_basicNotifications.Remove(notificationId);
}
else if (_progressNotification.ContainsKey(notificationId))
{
_progressNotification.Remove(notificationId);
}
}
}
}
}

View File

@ -0,0 +1,13 @@
.ui-notify { width:350px; position:fixed; top:10px; right:10px; }
.ui-notify-message { padding:10px; margin-bottom:15px; -moz-border-radius:8px; -webkit-border-radius:8px; border-radius:8px }
.ui-notify-message h1 { font-size:14px; margin:0; padding:0 }
.ui-notify-message p { margin:3px 0; padding:0; line-height:18px }
.ui-notify-message:last-child { margin-bottom:0 }
.ui-notify-message-style { background:#000; background:rgba(0,0,0,0.8); -moz-box-shadow: 0 0 6px #000; -webkit-box-shadow: 0 0 6px #000; box-shadow: 0 0 6px #000; }
.ui-notify-message-style h1 { color:#fff; font-weight:bold }
.ui-notify-message-style p { color:#fff }
.ui-notify-close { color:#fff; text-decoration:underline }
.ui-notify-click { cursor:pointer }
.ui-notify-cross { margin-top:-4px; float:right; cursor:pointer; text-decoration:none; font-size:12px; font-weight:bold; text-shadow:0 1px 1px #fff; padding:2px }
.ui-notify-cross:hover { color:#ffffab }
.ui-notify-cross:active { position:relative; top:1px }

View File

@ -9,7 +9,6 @@ namespace NzbDrone.Web
{ {
public class MvcApplication : NinjectHttpApplication public class MvcApplication : NinjectHttpApplication
{ {
private StandardKernel _kernel;
public static void RegisterRoutes(RouteCollection routes) public static void RegisterRoutes(RouteCollection routes)
{ {
@ -35,9 +34,8 @@ namespace NzbDrone.Web
protected override IKernel CreateKernel() protected override IKernel CreateKernel()
{ {
_kernel = new StandardKernel(); return CentralDispatch.NinjectKernel;
CentralDispatch.BindKernel(_kernel);
return _kernel;
} }

View File

@ -161,6 +161,7 @@
<Content Include="Content\Telerik\sprite.png" /> <Content Include="Content\Telerik\sprite.png" />
<Content Include="Content\Telerik\treeview-line.png" /> <Content Include="Content\Telerik\treeview-line.png" />
<Content Include="Content\Telerik\treeview-nodes.png" /> <Content Include="Content\Telerik\treeview-nodes.png" />
<Content Include="Content\ui.notify.css" />
<Content Include="Content\Vista\editor.png" /> <Content Include="Content\Vista\editor.png" />
<Content Include="Content\Vista\loading.gif" /> <Content Include="Content\Vista\loading.gif" />
<Content Include="Content\Vista\sprite.png" /> <Content Include="Content\Vista\sprite.png" />
@ -201,6 +202,8 @@
<Content Include="Scripts\2010.2.825\telerik.textbox.min.js" /> <Content Include="Scripts\2010.2.825\telerik.textbox.min.js" />
<Content Include="Scripts\2010.2.825\telerik.treeview.min.js" /> <Content Include="Scripts\2010.2.825\telerik.treeview.min.js" />
<Content Include="Scripts\2010.2.825\telerik.window.min.js" /> <Content Include="Scripts\2010.2.825\telerik.window.min.js" />
<Content Include="Scripts\jquery.msg.js" />
<Content Include="Scripts\Notifications.js" />
<Content Include="Views\Series\Details.aspx" /> <Content Include="Views\Series\Details.aspx" />
<Content Include="Views\Series\index.aspx" /> <Content Include="Views\Series\index.aspx" />
<Content Include="Views\Series\Unmapped.aspx" /> <Content Include="Views\Series\Unmapped.aspx" />

View File

@ -0,0 +1,12 @@
/// <reference path="jquery-1.4.1-vsdoc.js" />
$(function () {
alert("Notification");
var container = $("#container-bottom").notify({ stack: 'above' });
container.notify("create", {
title: 'Look ma, two containers!',
text: 'This container is positioned on the bottom of the screen. Notifications will stack on top of each other with the <code>position</code> attribute set to <code>above</code>.'
}, { expires: false });
});

View File

@ -0,0 +1,97 @@
/*
Copyright (c) 2010 Diego Uría Martínez
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/**
* Add a message to the body.
*
* Example:
* $('a').click(function() {
* $.fn.jQueryMsg({
* msg: 'Hello world!!'
* });
* });
*
* TODO:
* - don't set 'speed' too high, it may loose some events
* - option: message tag
* - option: content tag
*/
(function($,undefined){
var name = 'jQueryMsg';
var timeout;
$.fn.jQueryMsg = function(params)
{
var settings = $.extend(
{},
{
msgClass : 'jquerymsgclass', //container class
speed : 0, //effects' speed
delay: 100, //delay between messages
timeout: 3000, //maximum time the message is shown on the screen. 0 for permanent
fx: 'none' //effect: set it to none, fade or slide
},
params);
if(typeof(settings.msg) === 'string')
{
var show = {width: 'show', height: 'show'};
var hide = {width: 'hide', height: 'hide'};
switch(settings.fx) {
case 'fade':
show = {opacity: 'show'};
hide = {opacity: 'hide'};
break;
case 'slide':
show = {height: 'show'};
hide = {height: 'hide'};
break;
}
var msg;
if($('p.'+name).size() > 0) {
msg = $('p.'+name);
msg.click().delay(settings.delay);
}
else {
msg = $('<p class="'+name+'"></p>');
msg.hide().appendTo('body');
}
clearTimeout(timeout);
msg.one('click',function() {
msg.animate(hide, settings.speed, function() {
msg.removeClass().addClass(name);
});
}).queue(function() {
msg.html(settings.msg).addClass(settings.msgClass).animate(show, settings.speed).dequeue();
if(settings.timeout > 0) {
timeout = setTimeout(function() {
msg.click();
}, settings.timeout);
}
});
}
}
})(jQuery);

View File

@ -1,10 +1,4 @@
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %> <!--
<%@ Import Namespace="Helpers" %>
<%@ Import Namespace="Telerik.Web.Mvc.UI" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!--
Design by Free CSS Templates Design by Free CSS Templates
http://www.freecsstemplates.org http://www.freecsstemplates.org
Released for free under a Creative Commons Attribution 2.5 License Released for free under a Creative Commons Attribution 2.5 License
@ -13,42 +7,28 @@ Name : Concurrence
Description: A two-column, fixed-width design for 1024x768 screen resolutions. Description: A two-column, fixed-width design for 1024x768 screen resolutions.
Version : 1.0 Version : 1.0
Released : 20100727 Released : 20100727
--> -->
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<%@ Import Namespace="Helpers" %>
<%@ Import Namespace="Telerik.Web.Mvc.UI" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>NZBDrone </title> <title>NZBDrone</title>
<% <%
Html.Telerik().StyleSheetRegistrar().DefaultGroup(group => group.Add("telerik.common.css").Add("telerik.sitefinity.css")).Render(); Html.Telerik().StyleSheetRegistrar().DefaultGroup(group => group.Add("telerik.common.css").Add("telerik.sitefinity.css")).Render();
%> %>
<link href="../../Content/ui.notify.css" rel="stylesheet" type="text/css" />
<script src="../../Scripts/jquery.msg.js" type="text/javascript"></script>
<link href="../../Content/style.css" rel="stylesheet" type="text/css" media="screen" /> <link href="../../Content/style.css" rel="stylesheet" type="text/css" media="screen" />
<style>
.Mediabox
{
background:black;
}
.Play
{
cursor:pointer;
padding:5px;
}
.Pause
{
cursor:pointer;
padding:5px;
}
.Stop
{
cursor:pointer;
padding:5px;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="../../Scripts/Notifications.js" type="text/javascript"></script>
<script type="text/javascript"> <script type="text/javascript">
<asp:ContentPlaceHolder ID="JavascriptContent" runat="server" /> <asp:ContentPlaceHolder ID="JavascriptContent" runat="server" />
</script> </script>
</head> </head>
<body> <body>
<div id="header"> <div id="header">
@ -78,6 +58,24 @@ Released : 20100727
</div> </div>
</div> </div>
</div> </div>
<div id="container-bottom" style="display: none; top: auto; right: 0; padding: 10px;
bottom: 0; margin: 0 0 10px 10px">
<div>
<h1>
#{title}</h1>
<p>
#{text}</p>
<p style="margin-top: 10px; text-align: center">
<input type="button" class="confirm" value="Create Another Notification!" />
</p>
</div>
<div>
<h1>
#{title}</h1>
<p>
#{text}</p>
</div>
</div>
<div id="footer"> <div id="footer">
<p class="style1"> <p class="style1">
Design by Free CSS Templates.</p> Design by Free CSS Templates.</p>

View File

@ -1,12 +1,7 @@
using System; using NLog;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using NLog;
using NzbDrone.Core; using NzbDrone.Core;
namespace NzbDrone.Console namespace NzbDrone
{ {
class Program class Program
{ {
@ -15,6 +10,8 @@ namespace NzbDrone.Console
static void Main(string[] args) static void Main(string[] args)
{ {
CentralDispatch.ConfigureNlog(); CentralDispatch.ConfigureNlog();
CentralDispatch.BindKernel();
Logger.Info("Starting NZBDrone WebUI"); Logger.Info("Starting NZBDrone WebUI");
var server = new CassiniDev.Server(@"D:\My Dropbox\Git\NzbDrone\NzbDrone.Web"); var server = new CassiniDev.Server(@"D:\My Dropbox\Git\NzbDrone\NzbDrone.Web");
server.Start(); server.Start();

View File

@ -1,9 +1,7 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<configuration> <configuration>
<startup> <startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup> </startup>
<connectionStrings>
<add name="sqlite" connectionString="Data Source=filename;Version=3;"/>
</connectionStrings>
</configuration> </configuration>