├── .gitattributes
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.CN.md
├── README.md
├── examples
├── ExternalAppConfig
│ └── NRack.Server.exe.config
├── IsolationConfig
│ └── NRack.Server.exe.config
└── TestApp
│ ├── TestApp.sln
│ └── TestApp
│ ├── NRack.Examples.TestApp.csproj
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── TestAppServer.cs
│ └── packages.config
├── global.json
└── src
├── Build.bat
├── CreateNuGetPackage.bat
├── GlobalAssemblyInfo.cs
├── NRack-Net45.sln
├── NRack.Base
├── AppServer.ConfigHotUpdate.cs
├── AppServer.cs
├── CompositeTargtes
│ ├── CompositeTargetBase.cs
│ ├── LoggerFactoryCompositeTarget.cs
│ ├── MultipleResultCompositeTarget.cs
│ └── SingleResultCompositeTarget.cs
├── Config
│ ├── ConfigurationElementBase.cs
│ ├── GenericConfigurationElementCollectionBase.cs
│ ├── HotUpdateAttribute.cs
│ ├── IConfigSource.cs
│ ├── IServerConfig.cs
│ ├── NRackConfig.cs
│ └── ServerConfig.cs
├── Configuration
│ ├── ConfigurationExtension.cs
│ ├── NRackConfigSection.cs
│ └── ServerConfigElement.cs
├── DotNetCore
│ ├── CompositionContainer.cs
│ ├── ExportProvider.cs
│ ├── FakeAttributes.cs
│ └── LoggingExtensions.cs
├── ErrorEventArgs.cs
├── Extensions.cs
├── IAppEndPoint.cs
├── IAppServer.cs
├── IBootstrap.cs
├── ICompositeTarget.cs
├── IManagedApp.cs
├── IMessageBus.cs
├── IStatusCollector.cs
├── IsolationMode.cs
├── Metadata
│ ├── AppServerMetadata.cs
│ ├── AppServerMetadataAttribute.cs
│ ├── IAppServerMetadata.cs
│ ├── StatusInfoAttribute.cs
│ └── StatusInfoKeys.cs
├── NRack.Base.Net45.csproj
├── NRack.Base.NetCore.csproj
├── NRack.Base.csproj
├── NRack.Base.csproj.nuspec
├── NRackEnv.cs
├── Properties
│ └── AssemblyInfo.cs
├── Provider
│ ├── IProviderMetadata.cs
│ └── ProviderMetadataAttribute.cs
├── ServerState.cs
├── StartupType.cs
├── StatusInfoCollection.cs
├── packages.NRack.Base.Net45.config
└── packages.NRack.Base.config
├── NRack.Server
├── App.config
├── BootstrapBase.cs
├── BootstrapFactory.cs
├── Config
│ ├── log4net.config
│ └── nlog.config
├── ConfigurationWatcher.cs
├── ControlCommand.cs
├── DefaultBootstrap.cs
├── DefaultStatusCollector.cs
├── IRemoteManagedApp.cs
├── Isolation
│ ├── AppAssemblyUpdateState.cs
│ ├── AppDomainIsolation
│ │ ├── AppDomainApp.cs
│ │ └── AppDomainBootstrap.cs
│ ├── AssemblyImport.cs
│ ├── IsolationApp.cs
│ ├── IsolationBootstrap.cs
│ ├── MarshalManagedApp.cs
│ └── ProcessIsolation
│ │ ├── ExternalProcessApp.cs
│ │ ├── ExternalProcessAppServerMetadata.cs
│ │ ├── ProcessApp.cs
│ │ ├── ProcessBootstrap.cs
│ │ └── ProcessLocker.cs
├── MefExtensions.cs
├── NRack.Server.Net45.csproj
├── NRack.Server.csproj
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
├── Recycle
│ ├── AssemblyUpdatedRecycleTrigger.cs
│ ├── IRecycleTrigger.cs
│ ├── MemoryRecycleTrigger.cs
│ └── RecycleTriggerConfig.cs
├── RemoteAppGroup.cs
├── RemoteAppTypeValidator.cs
├── RemoteBootstrapProxy.cs
├── Service
│ ├── NRackService.Designer.cs
│ ├── NRackService.cs
│ ├── NRackServiceInstaller.Designer.cs
│ ├── NRackServiceInstaller.cs
│ └── SelfInstaller.cs
├── Utils
│ ├── PerformanceCounterInfo.cs
│ └── ProcessPerformanceCounter.cs
├── nrack.cmd
├── nrack.sh
├── packages.NRack.Server.Net45.config
└── packages.NRack.Server.config
├── NRack.Test
├── AppDomainIsolationTest.cs
├── Asserts
│ └── Config
│ │ ├── AppDomainIsolation.config
│ │ ├── Basic.config
│ │ └── ProcessIsolation.config
├── NRack.Test.Net45.csproj
├── NRack.Test.csproj
├── ProcessIsolationTest.cs
├── Test.cs
├── TestAppServer.cs
├── packages.NRack.Test.Net45.config
└── packages.NRack.Test.config
├── NRack.Worker
├── ManagedAppWorker.cs
├── NRack.Worker.Net45.csproj
├── NRack.Worker.csproj
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
├── packages.NRack.Worker.Net45.config
└── packages.NRack.Worker.config
├── NRack.build
├── NRack.nuspec
└── NRack.sln
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 | [Dd]ebug/
11 | [Dd]ebugPublic/
12 | [Rr]elease/
13 | x64/
14 | build/
15 | bld/
16 | [Bb]in/
17 | [Oo]bj/
18 |
19 | # MSTest test Results
20 | [Tt]est[Rr]esult*/
21 | [Bb]uild[Ll]og.*
22 |
23 | #NUNIT
24 | *.VisualState.xml
25 | TestResult.xml
26 |
27 | # Build Results of an ATL Project
28 | [Dd]ebugPS/
29 | [Rr]eleasePS/
30 | dlldata.c
31 |
32 | *_i.c
33 | *_p.c
34 | *_i.h
35 | *.ilk
36 | *.meta
37 | *.obj
38 | *.pch
39 | *.pdb
40 | *.pgc
41 | *.pgd
42 | *.rsp
43 | *.sbr
44 | *.tlb
45 | *.tli
46 | *.tlh
47 | *.tmp
48 | *.tmp_proj
49 | *.log
50 | *.vspscc
51 | *.vssscc
52 | .builds
53 | *.pidb
54 | *.svclog
55 | *.scc
56 |
57 | # Chutzpah Test files
58 | _Chutzpah*
59 |
60 | # Visual C++ cache files
61 | ipch/
62 | *.aps
63 | *.ncb
64 | *.opensdf
65 | *.sdf
66 | *.cachefile
67 |
68 | # Visual Studio profiler
69 | *.psess
70 | *.vsp
71 | *.vspx
72 |
73 | # TFS 2012 Local Workspace
74 | $tf/
75 |
76 | # Guidance Automation Toolkit
77 | *.gpState
78 |
79 | # ReSharper is a .NET coding add-in
80 | _ReSharper*/
81 | *.[Rr]e[Ss]harper
82 | *.DotSettings.user
83 |
84 | # JustCode is a .NET coding addin-in
85 | .JustCode
86 |
87 | # TeamCity is a build add-in
88 | _TeamCity*
89 |
90 | # DotCover is a Code Coverage Tool
91 | *.dotCover
92 |
93 | # NCrunch
94 | *.ncrunch*
95 | _NCrunch_*
96 | .*crunch*.local.xml
97 |
98 | # MightyMoose
99 | *.mm.*
100 | AutoTest.Net/
101 |
102 | # Web workbench (sass)
103 | .sass-cache/
104 |
105 | # Installshield output folder
106 | [Ee]xpress/
107 |
108 | # DocProject is a documentation generator add-in
109 | DocProject/buildhelp/
110 | DocProject/Help/*.HxT
111 | DocProject/Help/*.HxC
112 | DocProject/Help/*.hhc
113 | DocProject/Help/*.hhk
114 | DocProject/Help/*.hhp
115 | DocProject/Help/Html2
116 | DocProject/Help/html
117 |
118 | # Click-Once directory
119 | publish/
120 |
121 | # Publish Web Output
122 | *.[Pp]ublish.xml
123 | *.azurePubxml
124 |
125 | # NuGet Packages Directory
126 | packages/
127 | ## TODO: If the tool you use requires repositories.config uncomment the next line
128 | #!packages/repositories.config
129 |
130 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
131 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented)
132 | !packages/build/
133 |
134 | # Windows Azure Build Output
135 | csx/
136 | *.build.csdef
137 |
138 | # Windows Store app package directory
139 | AppPackages/
140 |
141 | # Others
142 | sql/
143 | *.Cache
144 | ClientBin/
145 | [Ss]tyle[Cc]op.*
146 | ~$*
147 | *~
148 | *.dbmdl
149 | *.dbproj.schemaview
150 | *.pfx
151 | *.publishsettings
152 | node_modules/
153 |
154 | # RIA/Silverlight projects
155 | Generated_Code/
156 |
157 | # Backup & report files from converting an old project file to a newer
158 | # Visual Studio version. Backup files are not needed, because we have git ;-)
159 | _UpgradeReport_Files/
160 | Backup*/
161 | UpgradeLog*.XML
162 | UpgradeLog*.htm
163 |
164 | # SQL Server files
165 | *.mdf
166 | *.ldf
167 |
168 | # Business Intelligence projects
169 | *.rdl.data
170 | *.bim.layout
171 | *.bim_*.settings
172 |
173 | # Microsoft Fakes
174 | FakesAssemblies/
175 |
176 | # dotnet core
177 | *.lock.json
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: csharp
2 | script:
3 | - nuget restore src/NRack.sln
4 | - xbuild src/NRack.sln
5 | - nuget restore src/NRack-Net45.sln
6 | - xbuild src/NRack-Net45.sln
7 |
--------------------------------------------------------------------------------
/README.CN.md:
--------------------------------------------------------------------------------
1 | NRack [](https://travis-ci.org/kerryjiang/NRack) [](https://www.nuget.org/packages/NRack/)
2 | =====
3 |
4 | **NRack** 是一个服务器应用容器, 他能用宿主和管理你的多个后端服务。
5 |
6 | **功能特点**:
7 |
8 | * **自动化服务宿主**: 宿主你的多个后端程序,无需为每个程序创建服务;
9 | * **外部程序宿主**: 宿主外部的可执行程序,可支持任何可执行程序,无论它是否是.NET开发;
10 | * **多应用隔离**: 支持多个程序的应用程序域级别的隔离或者进程级别的隔离;
11 | * **守护进程** : 程序意外关闭后自动启动;
12 | * **自动化回收管理**: 达到一定条件后自动重启程序;
13 | * **应用程序花园(TODO)**: 为同一应用运行多个实例;
14 | * **计划任务(TODO)**: 定时按计划运行制定程序。
15 |
16 | 文档: [http://nrack.getdocs.net/](http://nrack.getdocs.net/)
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | NRack [](https://travis-ci.org/kerryjiang/NRack) [](https://www.nuget.org/packages/NRack/)
2 | =====
3 |
4 | **NRack** is a server application container, which can be used for your back end services' hosting and management.
5 |
6 | **Features**:
7 |
8 | * **Automatic service hosting**: host your many backend applications, needn't create service for each application;
9 | * **External application hosting**: host external executable application, no matter whether it is developed using .NET;
10 | * **Multiple application isolation**: support isolate your multiple applications using AppDomain and process;
11 | * **Watch dog**: start application after it stops unexpected;
12 | * **Automatic recycle management**: restart application automatically after it satisify some conditions;
13 | * **App Garden(TODO)**: run one application in multiple instances;
14 | * **Task Scheduler(TODO)**: run the designate application on schedule.
15 |
16 | Documentation: [http://nrack.getdocs.net/](http://nrack.getdocs.net/)
17 |
--------------------------------------------------------------------------------
/examples/ExternalAppConfig/NRack.Server.exe.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 |
15 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/examples/IsolationConfig/NRack.Server.exe.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
13 |
14 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/examples/TestApp/TestApp.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25123.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRack.Examples.TestApp", "TestApp\NRack.Examples.TestApp.csproj", "{E23EDFA0-19AD-44EF-A35B-985F1D0A407D}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {E23EDFA0-19AD-44EF-A35B-985F1D0A407D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {E23EDFA0-19AD-44EF-A35B-985F1D0A407D}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {E23EDFA0-19AD-44EF-A35B-985F1D0A407D}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {E23EDFA0-19AD-44EF-A35B-985F1D0A407D}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/examples/TestApp/TestApp/NRack.Examples.TestApp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {E23EDFA0-19AD-44EF-A35B-985F1D0A407D}
8 | Library
9 | Properties
10 | NRack.Examples.TestApp
11 | NRack.Examples.TestApp
12 | v4.0
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 | ..\packages\AnyLog.0.1.8\lib\net40\AnyLog.dll
35 | True
36 |
37 |
38 | ..\packages\NRack.0.1.1.5\lib\net40\NRack.Base.dll
39 | True
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
64 |
--------------------------------------------------------------------------------
/examples/TestApp/TestApp/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("TestApp")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("TestApp")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("e23edfa0-19ad-44ef-a35b-985f1d0a407d")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/examples/TestApp/TestApp/TestAppServer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using NRack.Base;
6 | using NRack.Base.Metadata;
7 |
8 | namespace NRack.Examples.TestApp
9 | {
10 | [AppServerMetadata("TestAppServer")]
11 | public class TestAppServer : AppServer
12 | {
13 | public override bool Start()
14 | {
15 | Console.WriteLine("This AppServer is started");
16 | return true;
17 | }
18 |
19 | public override void Stop()
20 | {
21 |
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/examples/TestApp/TestApp/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "projects": [
3 | "src"
4 | ],
5 | "sdk": {
6 | "version": "1.0.0-rc2-*"
7 | }
8 | }
--------------------------------------------------------------------------------
/src/Build.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | set fdir=%ProgramFiles(x86)%\MSBuild\14.0
4 | set msbuild="%fdir%\bin\msbuild.exe"
5 |
6 |
7 | FOR /F "tokens=*" %%G IN ('DIR /B /AD /S obj') DO RMDIR /S /Q "%%G"
8 | %msbuild% NDock.sln /p:Configuration=Release /t:Clean;Rebuild /p:OutputPath=..\bin\Net40
9 |
10 | reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.5" 2>nul
11 | if errorlevel 0 (
12 | FOR /F "tokens=*" %%G IN ('DIR /B /AD /S obj') DO RMDIR /S /Q "%%G"
13 | %msbuild% NDock-Net45.sln /p:Configuration=Release /t:Clean;Rebuild /p:OutputPath=..\bin\Net45
14 | )
15 |
16 | pause
--------------------------------------------------------------------------------
/src/CreateNuGetPackage.bat:
--------------------------------------------------------------------------------
1 | set msbuild="%ProgramFiles(x86)%\MSBuild\14.0\Bin\msbuild.exe"
2 |
3 |
4 | %msbuild% NRack.build /t:BuildAndPack
5 |
6 | pause
--------------------------------------------------------------------------------
/src/GlobalAssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | [assembly: AssemblyCompany("NRack")]
6 | [assembly: AssemblyProduct("NRack")]
7 | [assembly: AssemblyCopyright("Copyright © 2016")]
8 | [assembly: AssemblyTrademark("")]
9 | [assembly: AssemblyCulture("")]
10 | [assembly: AssemblyVersion("0.1.1.5")]
11 | [assembly: AssemblyFileVersion("0.1.1.5")]
12 |
--------------------------------------------------------------------------------
/src/NRack-Net45.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25123.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRack.Base.Net45", "NRack.Base\NRack.Base.Net45.csproj", "{406671C6-5DCB-4B23-BD28-FB02C235EAE4}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRack.Server.Net45", "NRack.Server\NRack.Server.Net45.csproj", "{7800B7EA-FB3A-4305-9EE7-74A7B5744C45}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{6E0C838A-35D5-4D95-B3F0-6D0560F9C2FD}"
11 | ProjectSection(SolutionItems) = preProject
12 | GlobalAssemblyInfo.cs = GlobalAssemblyInfo.cs
13 | EndProjectSection
14 | EndProject
15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRack.Test.Net45", "NRack.Test\NRack.Test.Net45.csproj", "{B145DFCA-3A62-4FC6-A3F1-EA970719DC9F}"
16 | EndProject
17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRack.Worker.Net45", "NRack.Worker\NRack.Worker.Net45.csproj", "{93A2E31D-9AF3-4C9E-986C-1659309F5436}"
18 | EndProject
19 | Global
20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
21 | Debug|Any CPU = Debug|Any CPU
22 | Release|Any CPU = Release|Any CPU
23 | EndGlobalSection
24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
25 | {406671C6-5DCB-4B23-BD28-FB02C235EAE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 | {406671C6-5DCB-4B23-BD28-FB02C235EAE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 | {406671C6-5DCB-4B23-BD28-FB02C235EAE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 | {406671C6-5DCB-4B23-BD28-FB02C235EAE4}.Release|Any CPU.Build.0 = Release|Any CPU
29 | {7800B7EA-FB3A-4305-9EE7-74A7B5744C45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30 | {7800B7EA-FB3A-4305-9EE7-74A7B5744C45}.Debug|Any CPU.Build.0 = Debug|Any CPU
31 | {7800B7EA-FB3A-4305-9EE7-74A7B5744C45}.Release|Any CPU.ActiveCfg = Release|Any CPU
32 | {7800B7EA-FB3A-4305-9EE7-74A7B5744C45}.Release|Any CPU.Build.0 = Release|Any CPU
33 | {B145DFCA-3A62-4FC6-A3F1-EA970719DC9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 | {B145DFCA-3A62-4FC6-A3F1-EA970719DC9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
35 | {B145DFCA-3A62-4FC6-A3F1-EA970719DC9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
36 | {93A2E31D-9AF3-4C9E-986C-1659309F5436}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37 | {93A2E31D-9AF3-4C9E-986C-1659309F5436}.Debug|Any CPU.Build.0 = Debug|Any CPU
38 | {93A2E31D-9AF3-4C9E-986C-1659309F5436}.Release|Any CPU.ActiveCfg = Release|Any CPU
39 | {93A2E31D-9AF3-4C9E-986C-1659309F5436}.Release|Any CPU.Build.0 = Release|Any CPU
40 | EndGlobalSection
41 | GlobalSection(SolutionProperties) = preSolution
42 | HideSolutionNode = FALSE
43 | EndGlobalSection
44 | EndGlobal
45 |
--------------------------------------------------------------------------------
/src/NRack.Base/AppServer.ConfigHotUpdate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Specialized;
4 | #if !DOTNETCORE
5 | using System.Configuration;
6 | using NRack.Base.Configuration;
7 | #else
8 | using Microsoft.Extensions.Logging;
9 | using System.Reflection;
10 | #endif
11 | using System.Linq;
12 | using NRack.Base.Config;
13 |
14 |
15 | namespace NRack.Base
16 | {
17 | interface IConfigValueChangeNotifier
18 | {
19 | bool Notify(string newValue);
20 | }
21 |
22 | class ConfigValueChangeNotifier : IConfigValueChangeNotifier
23 | {
24 | Func m_Handler;
25 |
26 | public ConfigValueChangeNotifier(Func handler)
27 | {
28 | m_Handler = handler;
29 | }
30 |
31 | public bool Notify(string newValue)
32 | {
33 | return m_Handler(newValue);
34 | }
35 | }
36 |
37 | #if !DOTNETCORE
38 | class ConfigValueChangeNotifier : IConfigValueChangeNotifier
39 | where TConfigOption : ConfigurationElement, new()
40 | {
41 | Func m_Handler;
42 |
43 | public ConfigValueChangeNotifier(Func handler)
44 | {
45 | m_Handler = handler;
46 | }
47 | public bool Notify(string newValue)
48 | {
49 | if (string.IsNullOrEmpty(newValue))
50 | return m_Handler(default(TConfigOption));
51 | else
52 | return m_Handler(ConfigurationExtension.DeserializeChildConfig(newValue));
53 | }
54 | }
55 | #endif
56 | public abstract partial class AppServer
57 | {
58 | private Dictionary m_ConfigUpdatedNotifiers = new Dictionary(StringComparer.OrdinalIgnoreCase);
59 |
60 | #if !DOTNETCORE
61 | ///
62 | /// Registers the configuration option value handler, it is used for reading configuration value and reload it after the configuration is changed;
63 | ///
64 | /// The type of the configuration option.
65 | /// The server configuration.
66 | /// The changed config option's name.
67 | /// The handler.
68 | protected bool RegisterConfigHandler(IServerConfig config, string name, Func handler)
69 | where TConfigOption : ConfigurationElement, new()
70 | {
71 | var notifier = new ConfigValueChangeNotifier(handler);
72 | m_ConfigUpdatedNotifiers.Add(name, notifier);
73 | return notifier.Notify(config.Options.GetValue(name));
74 | }
75 | #endif
76 |
77 | ///
78 | /// Registers the configuration option value handler, it is used for reading configuration value and reload it after the configuration is changed;
79 | ///
80 | /// The server configuration.
81 | /// The changed config option name.
82 | /// The handler.
83 | protected bool RegisterConfigHandler(IServerConfig config, string name, Func handler)
84 | {
85 | var notifier = new ConfigValueChangeNotifier(handler);
86 | m_ConfigUpdatedNotifiers.Add(name, notifier);
87 | return notifier.Notify(config.OptionElements.GetValue(name));
88 | }
89 |
90 | int CheckConfigOptionsChange(NameValueCollection oldOptions, NameValueCollection newOptions)
91 | {
92 | var changed = 0;
93 |
94 | if (oldOptions == null && newOptions == null)
95 | return changed;
96 |
97 | var oldOptionsDict = oldOptions == null
98 | ? new Dictionary(StringComparer.OrdinalIgnoreCase)
99 | : Enumerable.Range(0, oldOptions.Count)
100 | .Select(i => new KeyValuePair(oldOptions.GetKey(i), oldOptions.Get(i)))
101 | .ToDictionary(p => p.Key, p => p.Value, StringComparer.OrdinalIgnoreCase);
102 |
103 | foreach(var key in newOptions.AllKeys)
104 | {
105 | var newValue = newOptions[key];
106 |
107 | var oldValue = string.Empty;
108 |
109 | if (oldOptionsDict.TryGetValue(key, out oldValue))
110 | oldOptionsDict.Remove(key);
111 |
112 | if (string.Compare(newValue, oldValue) == 0)
113 | continue;
114 |
115 | NotifyConfigUpdated(key, newValue);
116 | changed++;
117 | }
118 |
119 | if (oldOptionsDict.Count > 0)
120 | {
121 | foreach (var p in oldOptionsDict)
122 | {
123 | NotifyConfigUpdated(p.Key, string.Empty);
124 | changed++;
125 | }
126 | }
127 |
128 | return changed;
129 | }
130 |
131 | private void NotifyConfigUpdated(string key, string newValue)
132 | {
133 | IConfigValueChangeNotifier notifier;
134 |
135 | if (!m_ConfigUpdatedNotifiers.TryGetValue(key, out notifier))
136 | return;
137 |
138 | try
139 | {
140 | if (!notifier.Notify(newValue))
141 | throw new Exception("returned false in the handling logic");
142 | }
143 | catch (Exception e)
144 | {
145 | Logger.Error("Failed to handle custom configuration reading, name: " + key, e);
146 | }
147 | }
148 |
149 | void IManagedAppBase.ReportPotentialConfigChange(IServerConfig config)
150 | {
151 | var oldConfig = this.Config;
152 |
153 | CheckConfigOptionsChange(oldConfig.Options, config.Options);
154 | CheckConfigOptionsChange(oldConfig.OptionElements, config.OptionElements);
155 |
156 | var updatableConfig = oldConfig as ServerConfig;
157 |
158 | if (updatableConfig == null)
159 | return;
160 |
161 | config.CopyPropertiesTo(p => p.GetCustomAttributes(typeof(HotUpdateAttribute), true).Any(), updatableConfig);
162 | }
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/src/NRack.Base/CompositeTargtes/CompositeTargetBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel.Composition.Hosting;
3 |
4 | namespace NRack.Base.CompositeTargets
5 | {
6 | ///
7 | /// the basic class of composite target
8 | ///
9 | /// The type of the target.
10 | public abstract class CompositeTargetBase : ICompositeTarget
11 | {
12 | private Action m_Callback;
13 |
14 | ///
15 | /// Initializes a new instance of the class.
16 | ///
17 | /// The callback which will be invoked after the resolving is finished successfully.
18 | protected CompositeTargetBase(Action callback)
19 | {
20 | m_Callback = callback;
21 | }
22 |
23 | ///
24 | /// Resolves the specified application server.
25 | ///
26 | /// The application server.
27 | /// The export provider.
28 | ///
29 | public bool Resolve(IAppServer appServer, ExportProvider exportProvider)
30 | {
31 | TTarget result = default(TTarget);
32 |
33 | if (!TryResolve(appServer, exportProvider, out result))
34 | return false;
35 |
36 | m_Callback(result);
37 | return true;
38 | }
39 |
40 | ///
41 | /// Tries to resolve.
42 | ///
43 | /// The application server.
44 | /// The export provider.
45 | /// The resolving result.
46 | ///
47 | protected abstract bool TryResolve(IAppServer appServer, ExportProvider exportProvider, out TTarget result);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/NRack.Base/CompositeTargtes/LoggerFactoryCompositeTarget.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.Composition.Hosting;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using AnyLog;
9 | using NRack.Base.Config;
10 |
11 | namespace NRack.Base.CompositeTargets
12 | {
13 | class LoggerFactoryCompositeTarget : SingleResultCompositeTargetCore
14 | {
15 | public LoggerFactoryCompositeTarget(Action callback)
16 | : base((config) => config.LogFactory, callback, true)
17 | {
18 |
19 | }
20 |
21 | protected override bool MetadataNameEqual(ILoggerFactoryMetadata metadata, string name)
22 | {
23 | return metadata.Name.Equals(name, StringComparison.OrdinalIgnoreCase);
24 | }
25 |
26 | protected override IEnumerable> Sort(IEnumerable> factories)
27 | {
28 | return factories.OrderBy(f => f.Metadata.Priority);
29 | }
30 |
31 | protected override bool PrepareResult(ILoggerFactory result, IAppServer appServer, ILoggerFactoryMetadata metadata)
32 | {
33 | if (string.IsNullOrEmpty(metadata.ConfigFileName))
34 | {
35 | return result.Initialize(new string[0]);
36 | }
37 |
38 | var currentAppDomain = AppDomain.CurrentDomain;
39 | var isolation = IsolationMode.None;
40 |
41 | var isolationValue = currentAppDomain.GetData(typeof(IsolationMode).Name);
42 |
43 | if (isolationValue != null)
44 | isolation = (IsolationMode)isolationValue;
45 |
46 | var configFileName = metadata.ConfigFileName;
47 |
48 | if (Path.DirectorySeparatorChar != '\\')
49 | {
50 | configFileName = Path.GetFileNameWithoutExtension(configFileName) + ".unix" + Path.GetExtension(configFileName);
51 | }
52 |
53 | var configFiles = new List();
54 |
55 | if (isolation == IsolationMode.None)
56 | {
57 | configFiles.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, configFileName));
58 | configFiles.Add(Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config"), configFileName));
59 | }
60 | else //The running AppServer is in isolated appdomain
61 | {
62 | configFiles.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, configFileName));
63 | configFiles.Add(Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config"), configFileName));
64 |
65 | //go to the application's root
66 | //the appdomain's root is /WorkingDir/DomainName, so get parent path twice to reach the application root
67 | var rootDir = Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).Parent.FullName;
68 |
69 | configFiles.Add(Path.Combine(rootDir, AppDomain.CurrentDomain.FriendlyName + "." + configFileName));
70 | configFiles.Add(Path.Combine(Path.Combine(rootDir, "Config"), AppDomain.CurrentDomain.FriendlyName + "." + configFileName));
71 | configFiles.Add(Path.Combine(rootDir, configFileName));
72 | configFiles.Add(Path.Combine(Path.Combine(rootDir, "Config"), configFileName));
73 | }
74 |
75 | if (!result.Initialize(configFiles.ToArray()))
76 | {
77 | appServer.Logger.Error("Failed to initialize the logfactory:" + metadata.Name);
78 | return false;
79 | }
80 |
81 | return true;
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/NRack.Base/Config/ConfigurationElementBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Specialized;
4 | using System.Configuration;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Xml;
8 |
9 | namespace NRack.Base.Config
10 | {
11 | ///
12 | /// ConfigurationElementBase
13 | ///
14 | [Serializable]
15 | public class ConfigurationElementBase : ConfigurationElement
16 | {
17 | private bool m_NameRequired;
18 |
19 | ///
20 | /// Initializes a new instance of the class.
21 | ///
22 | public ConfigurationElementBase()
23 | : this(true)
24 | {
25 |
26 | }
27 |
28 | ///
29 | /// Initializes a new instance of the class.
30 | ///
31 | /// if set to true [name required].
32 | public ConfigurationElementBase(bool nameRequired)
33 | {
34 | m_NameRequired = nameRequired;
35 | Options = new NameValueCollection();
36 | }
37 |
38 | ///
39 | /// Gets the name.
40 | ///
41 | [ConfigurationProperty("name")]
42 | public string Name
43 | {
44 | get { return this["name"] as string; }
45 | }
46 |
47 | ///
48 | /// Reads XML from the configuration file.
49 | ///
50 | /// The that reads from the configuration file.
51 | /// true to serialize only the collection key properties; otherwise, false.
52 | /// The element to read is locked.- or -An attribute of the current node is not recognized.- or -The lock status of the current node cannot be determined.
53 | protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey)
54 | {
55 | base.DeserializeElement(reader, serializeCollectionKey);
56 |
57 | if (m_NameRequired && string.IsNullOrEmpty(Name))
58 | {
59 | throw new ConfigurationErrorsException("Required attribute 'name' not found.");
60 | }
61 | }
62 |
63 | ///
64 | /// Gets the options.
65 | ///
66 | public NameValueCollection Options { get; private set; }
67 |
68 | ///
69 | /// Gets a value indicating whether an unknown attribute is encountered during deserialization.
70 | ///
71 | /// The name of the unrecognized attribute.
72 | /// The value of the unrecognized attribute.
73 | ///
74 | /// true when an unknown attribute is encountered while deserializing; otherwise, false.
75 | ///
76 | protected override bool OnDeserializeUnrecognizedAttribute(string name, string value)
77 | {
78 | Options.Add(name, value);
79 | return true;
80 | }
81 |
82 | ///
83 | /// Gets the option elements.
84 | ///
85 | public NameValueCollection OptionElements { get; private set; }
86 |
87 | ///
88 | /// Gets a value indicating whether an unknown element is encountered during deserialization.
89 | ///
90 | /// The name of the unknown subelement.
91 | /// The being used for deserialization.
92 | ///
93 | /// true when an unknown element is encountered while deserializing; otherwise, false.
94 | ///
95 | /// The element identified by is locked.- or -One or more of the element's attributes is locked.- or - is unrecognized, or the element has an unrecognized attribute.- or -The element has a Boolean attribute with an invalid value.- or -An attempt was made to deserialize a property more than once.- or -An attempt was made to deserialize a property that is not a valid member of the element.- or -The element cannot contain a CDATA or text element.
96 | protected override bool OnDeserializeUnrecognizedElement(string elementName, System.Xml.XmlReader reader)
97 | {
98 | if (OptionElements == null)
99 | OptionElements = new NameValueCollection();
100 |
101 | OptionElements.Add(elementName, reader.ReadOuterXml());
102 | return true;
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/NRack.Base/Config/GenericConfigurationElementCollectionBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Linq;
5 | using System.Text;
6 |
7 | namespace NRack.Base.Config
8 | {
9 | ///
10 | /// GenericConfigurationElementCollectionBase
11 | ///
12 | /// The type of the config element.
13 | /// The type of the config interface.
14 | public class GenericConfigurationElementCollectionBase : ConfigurationElementCollection, IEnumerable
15 | where TConfigElement : ConfigurationElement, TConfigInterface, new()
16 | {
17 | ///
18 | /// Gets or sets a property, attribute, or child element of this configuration element.
19 | ///
20 | /// The specified property, attribute, or child element
21 | public TConfigElement this[int index]
22 | {
23 | get
24 | {
25 | return (TConfigElement)base.BaseGet(index);
26 | }
27 | set
28 | {
29 | if (base.BaseGet(index) != null)
30 | {
31 | base.BaseRemoveAt(index);
32 | }
33 | this.BaseAdd(index, value as ConfigurationElement);
34 | }
35 | }
36 |
37 | ///
38 | /// When overridden in a derived class, creates a new .
39 | ///
40 | ///
41 | /// A new .
42 | ///
43 | protected override ConfigurationElement CreateNewElement()
44 | {
45 | return new TConfigElement() as ConfigurationElement;
46 | }
47 |
48 | ///
49 | /// Gets the element key for a specified configuration element when overridden in a derived class.
50 | ///
51 | /// The to return the key for.
52 | ///
53 | /// An that acts as the key for the specified .
54 | ///
55 | protected override object GetElementKey(ConfigurationElement element)
56 | {
57 | return element;
58 | }
59 |
60 | #region IEnumerable[T] implementation
61 |
62 | ///
63 | /// Returns an enumerator that iterates through the collection.
64 | ///
65 | ///
66 | /// A that can be used to iterate through the collection.
67 | ///
68 | public new IEnumerator GetEnumerator()
69 | {
70 | int count = base.Count;
71 |
72 | for (int i = 0; i < count; i++)
73 | {
74 | yield return (TConfigElement)base.BaseGet(i);
75 | }
76 | }
77 |
78 | #endregion
79 | }
80 |
81 | ///
82 | /// Generic ConfigurationElement CollectionBase
83 | ///
84 | /// The type of the configuration element.
85 | public class GenericConfigurationElementCollectionBase : ConfigurationElementCollection, IEnumerable
86 | where TConfigElement : ConfigurationElement, new()
87 | {
88 | ///
89 | /// Gets or sets a property, attribute, or child element of this configuration element.
90 | ///
91 | /// The specified property, attribute, or child element
92 | public TConfigElement this[int index]
93 | {
94 | get
95 | {
96 | return (TConfigElement)base.BaseGet(index);
97 | }
98 | set
99 | {
100 | if (base.BaseGet(index) != null)
101 | {
102 | base.BaseRemoveAt(index);
103 | }
104 | this.BaseAdd(index, value as ConfigurationElement);
105 | }
106 | }
107 |
108 | ///
109 | /// When overridden in a derived class, creates a new .
110 | ///
111 | ///
112 | /// A new .
113 | ///
114 | protected override ConfigurationElement CreateNewElement()
115 | {
116 | return new TConfigElement() as ConfigurationElement;
117 | }
118 |
119 | ///
120 | /// Gets the element key for a specified configuration element when overridden in a derived class.
121 | ///
122 | /// The to return the key for.
123 | ///
124 | /// An that acts as the key for the specified .
125 | ///
126 | protected override object GetElementKey(ConfigurationElement element)
127 | {
128 | return element;
129 | }
130 |
131 | #region IEnumerable[T] implementation
132 |
133 | ///
134 | /// Returns an enumerator that iterates through the collection.
135 | ///
136 | ///
137 | /// A that can be used to iterate through the collection.
138 | ///
139 | public new IEnumerator GetEnumerator()
140 | {
141 | int count = base.Count;
142 |
143 | for (int i = 0; i < count; i++)
144 | {
145 | yield return (TConfigElement)base.BaseGet(i);
146 | }
147 | }
148 |
149 | #endregion
150 | }
151 |
152 | ///
153 | /// GenericConfigurationElementCollection
154 | ///
155 | /// The type of the config element.
156 | /// The type of the config interface.
157 | public class GenericConfigurationElementCollection : GenericConfigurationElementCollectionBase, IEnumerable
158 | where TConfigElement : ConfigurationElementBase, TConfigInterface, new()
159 | {
160 | ///
161 | /// Gets the element key.
162 | ///
163 | /// The element.
164 | ///
165 | protected override object GetElementKey(ConfigurationElement element)
166 | {
167 | return ((TConfigElement)element).Name;
168 | }
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/src/NRack.Base/Config/HotUpdateAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NRack.Base.Config
4 | {
5 | ///
6 | /// the attribute to mark which property of ServerConfig support hot update
7 | ///
8 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
9 | public class HotUpdateAttribute : Attribute
10 | {
11 |
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/NRack.Base/Config/IConfigSource.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace NRack.Base.Config
6 | {
7 | public interface IConfigSource
8 | {
9 | string LogFactory { get; }
10 |
11 | IsolationMode Isolation { get; }
12 |
13 | int StatusCollectInterval { get; }
14 |
15 | IEnumerable Servers { get; }
16 |
17 | int TcpRemotingPort { get; }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/NRack.Base/Config/IServerConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Specialized;
4 | using System.Text;
5 |
6 | namespace NRack.Base.Config
7 | {
8 | public interface IServerConfig
9 | {
10 | string Name { get; }
11 |
12 | string Group { get; }
13 |
14 | string Type { get; }
15 |
16 | string LogFactory { get; }
17 |
18 | StartupType StartupType { get; }
19 |
20 | NameValueCollection Options { get; }
21 |
22 | NameValueCollection OptionElements { get; }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/NRack.Base/Config/NRackConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace NRack.Base.Config
6 | {
7 | #if !DOTNETCORE
8 | [Serializable]
9 | #endif
10 | public class NRackConfig : IConfigSource
11 | {
12 | public const int DefaultTcpRemotingPort = 0;
13 |
14 | public NRackConfig()
15 | {
16 |
17 | }
18 |
19 | public NRackConfig(IConfigSource configSource)
20 | {
21 | Isolation = configSource.Isolation;
22 | LogFactory = configSource.LogFactory;
23 | StatusCollectInterval = configSource.StatusCollectInterval;
24 | TcpRemotingPort = DefaultTcpRemotingPort;
25 |
26 | if (configSource.Servers != null && configSource.Servers.Any())
27 | {
28 | this.Servers = configSource.Servers.Select(s => new ServerConfig(s)).ToArray();
29 | }
30 | }
31 |
32 | public IsolationMode Isolation { get; set; }
33 |
34 | public IEnumerable Servers { get; set; }
35 |
36 | public string LogFactory { get; set; }
37 |
38 | public int StatusCollectInterval { get; set; }
39 |
40 | public int TcpRemotingPort { get; set; }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/NRack.Base/Config/ServerConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Specialized;
4 | #if !DOTNETCORE
5 | using System.Configuration;
6 | using NRack.Base.Configuration;
7 | #endif
8 |
9 | namespace NRack.Base.Config
10 | {
11 | #if !DOTNETCORE
12 | [Serializable]
13 | #endif
14 | public class ServerConfig : IServerConfig
15 | {
16 | public ServerConfig()
17 | {
18 |
19 | }
20 |
21 | public ServerConfig(IServerConfig serverConfig)
22 | {
23 | #if !DOTNETCORE
24 | serverConfig.CopyPropertiesTo(this);
25 | #endif
26 | }
27 |
28 | public string Name { get; set; }
29 |
30 | public string Group { get; set; }
31 |
32 | public string Type { get; set; }
33 |
34 | public string LogFactory { get; set; }
35 |
36 | public StartupType StartupType { get; set; }
37 |
38 | public NameValueCollection Options { get; set; }
39 |
40 | public NameValueCollection OptionElements { get; set; }
41 |
42 | #if !DOTNETCORE
43 |
44 | ///
45 | /// Gets the child config.
46 | ///
47 | /// The type of the config.
48 | /// Name of the child config.
49 | ///
50 | public virtual TConfig GetChildConfig(string childConfigName)
51 | where TConfig : ConfigurationElement, new()
52 | {
53 | return this.OptionElements.GetChildConfig(childConfigName);
54 | }
55 | #endif
56 |
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/src/NRack.Base/Configuration/NRackConfigSection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Specialized;
4 | using System.Configuration;
5 | using System.Linq;
6 | using System.Text;
7 | using NRack.Base.Config;
8 |
9 | namespace NRack.Base.Configuration
10 | {
11 | public class NRackConfigSection : ConfigurationSection, IConfigSource
12 | {
13 | ///
14 | /// Gets the isolation mode.
15 | ///
16 | [ConfigurationProperty("isolation", IsRequired = false, DefaultValue = IsolationMode.None)]
17 | public IsolationMode Isolation
18 | {
19 | get { return (IsolationMode)this["isolation"]; }
20 | }
21 |
22 | [ConfigurationProperty("logFactory", IsRequired = false)]
23 | public string LogFactory
24 | {
25 | get { return (string)this["logFactory"]; }
26 | }
27 |
28 | [ConfigurationProperty("statusCollectInterval", IsRequired = false, DefaultValue = 60)]
29 | public int StatusCollectInterval
30 | {
31 | get { return (int)this["statusCollectInterval"]; }
32 | }
33 |
34 | [ConfigurationProperty("tcpRemotingPort", IsRequired = false, DefaultValue = NRackConfig.DefaultTcpRemotingPort)]
35 | public int TcpRemotingPort
36 | {
37 | get { return (int)this["tcpRemotingPort"]; }
38 | }
39 |
40 | ///
41 | /// Gets all the server configurations
42 | ///
43 | [ConfigurationProperty("servers")]
44 | public ServerCollection Servers
45 | {
46 | get
47 | {
48 | return this["servers"] as ServerCollection;
49 | }
50 | }
51 |
52 | IEnumerable IConfigSource.Servers
53 | {
54 | get { return this.Servers; }
55 | }
56 |
57 | ///
58 | /// Gets the option elements.
59 | ///
60 | public NameValueCollection OptionElements { get; private set; }
61 |
62 | ///
63 | /// Gets a value indicating whether an unknown element is encountered during deserialization.
64 | /// To keep compatible with old configuration
65 | ///
66 | /// The name of the unknown subelement.
67 | /// The being used for deserialization.
68 | ///
69 | /// true when an unknown element is encountered while deserializing; otherwise, false.
70 | ///
71 | /// The element identified by is locked.- or -One or more of the element's attributes is locked.- or - is unrecognized, or the element has an unrecognized attribute.- or -The element has a Boolean attribute with an invalid value.- or -An attempt was made to deserialize a property more than once.- or -An attempt was made to deserialize a property that is not a valid member of the element.- or -The element cannot contain a CDATA or text element.
72 | protected override bool OnDeserializeUnrecognizedElement(string elementName, System.Xml.XmlReader reader)
73 | {
74 | if (OptionElements == null)
75 | OptionElements = new NameValueCollection();
76 |
77 | OptionElements.Add(elementName, reader.ReadOuterXml());
78 | return true;
79 | }
80 |
81 | ///
82 | /// Gets a value indicating whether an unknown attribute is encountered during deserialization.
83 | ///
84 | /// The name of the unrecognized attribute.
85 | /// The value of the unrecognized attribute.
86 | ///
87 | /// true when an unknown attribute is encountered while deserializing; otherwise, false.
88 | ///
89 | protected override bool OnDeserializeUnrecognizedAttribute(string name, string value)
90 | {
91 | const string xmlns = "xmlns";
92 | const string xmlnsPrefix = "xmlns:";
93 | const string xsiPrefix = "xsi:";
94 |
95 | //for configuration intellisense, allow these unrecognized attributes: xmlns, xmlns:*, xsi:*
96 | if (name.Equals(xmlns) || name.StartsWith(xmlnsPrefix) || name.StartsWith(xsiPrefix))
97 | return true;
98 |
99 | return false;
100 | }
101 |
102 | ///
103 | /// Gets the child config.
104 | ///
105 | /// The type of the config.
106 | /// Name of the child config.
107 | ///
108 | public TConfig GetChildConfig(string childConfigName)
109 | where TConfig : ConfigurationElement, new()
110 | {
111 | return this.OptionElements.GetChildConfig(childConfigName);
112 | }
113 | }
114 |
115 | ///
116 | /// Server configuration collection
117 | ///
118 | [ConfigurationCollection(typeof(ServerConfigElement), AddItemName = "server")]
119 | public class ServerCollection : GenericConfigurationElementCollection
120 | {
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/NRack.Base/Configuration/ServerConfigElement.cs:
--------------------------------------------------------------------------------
1 | using NRack.Base.Config;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Configuration;
5 | using System.Linq;
6 | using System.Text;
7 |
8 | namespace NRack.Base.Configuration
9 | {
10 | public class ServerConfigElement : ConfigurationElementBase, IServerConfig
11 | {
12 | [ConfigurationProperty("group", IsRequired = false)]
13 | public string Group
14 | {
15 | get { return this["group"] as string; }
16 | }
17 |
18 | [ConfigurationProperty("type", IsRequired = false)]
19 | public string Type
20 | {
21 | get { return this["type"] as string; }
22 | }
23 |
24 | [ConfigurationProperty("logFactory", IsRequired = false)]
25 | public string LogFactory
26 | {
27 | get { return this["logFactory"] as string; }
28 | }
29 |
30 | [ConfigurationProperty("startupType", IsRequired = false)]
31 | public StartupType StartupType
32 | {
33 | get { return (StartupType)this["startupType"]; }
34 | }
35 |
36 | ///
37 | /// Gets the child config.
38 | ///
39 | /// The type of the config.
40 | /// Name of the child config.
41 | ///
42 | public TConfig GetChildConfig(string childConfigName)
43 | where TConfig : ConfigurationElement, new()
44 | {
45 | return this.OptionElements.GetChildConfig(childConfigName);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/NRack.Base/DotNetCore/CompositionContainer.cs:
--------------------------------------------------------------------------------
1 |
2 | using System.ComponentModel.Composition.Hosting;
3 |
4 | namespace System.ComponentModel.Composition
5 | {
6 | public class CompositionContainer : ExportProvider
7 | {
8 |
9 | }
10 | }
--------------------------------------------------------------------------------
/src/NRack.Base/DotNetCore/ExportProvider.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace System.ComponentModel.Composition.Hosting
4 | {
5 | public class ExportProvider
6 | {
7 | public IEnumerable> GetExports()
8 | {
9 | throw new NotImplementedException();
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/NRack.Base/DotNetCore/FakeAttributes.cs:
--------------------------------------------------------------------------------
1 | namespace System.Runtime.Serialization
2 | {
3 | [AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Property)]
4 | public class SerializableAttribute : Attribute
5 | {
6 |
7 | }
8 |
9 | public class NonSerializedAttribute : Attribute
10 | {
11 |
12 | }
13 |
14 | [AttributeUsageAttribute(AttributeTargets.Method)]
15 | public class OnSerializingAttribute : Attribute
16 | {
17 |
18 | }
19 |
20 | [AttributeUsageAttribute(AttributeTargets.Method)]
21 | public class OnDeserializedAttribute : Attribute
22 | {
23 |
24 | }
25 |
26 | public class StreamingContext
27 | {
28 |
29 | }
30 | }
--------------------------------------------------------------------------------
/src/NRack.Base/DotNetCore/LoggingExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.Extensions.Logging;
3 |
4 | namespace Microsoft.Extensions.Logging
5 | {
6 | public static class LoggingExtensions
7 | {
8 | public static void ErrorFormat(this ILogger logger, string message, params string[] args)
9 | {
10 | logger.LogError(null, message, args);
11 | }
12 |
13 | public static void Error(this ILogger logger, string message, Exception e)
14 | {
15 | logger.LogError(null, e, message);
16 | }
17 |
18 | public static void Error(this ILogger logger, string message)
19 | {
20 | logger.LogError(null, message);
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/src/NRack.Base/ErrorEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NRack.Base
4 | {
5 | public class ErrorEventArgs : EventArgs
6 | {
7 | public Exception Exception { get; private set; }
8 |
9 | public ErrorEventArgs(Exception exception)
10 | {
11 | Exception = exception;
12 | }
13 | }
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/src/NRack.Base/IAppEndPoint.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NRack.Base
4 | {
5 | ///
6 | /// The interface which can abtract the absolute address of one application instance in the whole system
7 | ///
8 | public interface IAppEndPoint
9 | {
10 | ///
11 | /// Gets the identity of one application instance.
12 | ///
13 | ///
14 | /// The identity.
15 | ///
16 | object Identity { get; }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/NRack.Base/IAppServer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | #if DOTNETCORE
4 | using ILog = Microsoft.Extensions.Logging.ILogger;
5 | #else
6 | using AnyLog;
7 | #endif
8 |
9 |
10 | namespace NRack.Base
11 | {
12 | public interface IAppServer : IManagedApp
13 | {
14 | ILog Logger { get; }
15 |
16 | IAppEndPoint EndPoint { get; }
17 |
18 | IMessageBus MessageBus { get; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/NRack.Base/IBootstrap.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace NRack.Base
5 | {
6 | public interface IBootstrap
7 | {
8 | ///
9 | /// Initializes this instance.
10 | ///
11 | ///
12 | bool Initialize();
13 |
14 | ///
15 | /// Gets all the app servers running in this bootstrap
16 | ///
17 | IEnumerable AppServers { get; }
18 |
19 | ///
20 | /// Starts this instance.
21 | ///
22 | void Start();
23 |
24 | ///
25 | /// Stops this instance.
26 | ///
27 | void Stop();
28 |
29 | ///
30 | /// Gets the configuration file path.
31 | ///
32 | ///
33 | /// The configuration file path.
34 | ///
35 | string ConfigFilePath { get; }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/NRack.Base/ICompositeTarget.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel.Composition.Hosting;
3 |
4 | namespace NRack.Base
5 | {
6 | ///
7 | /// The interface for the composite target
8 | ///
9 | public interface ICompositeTarget
10 | {
11 | ///
12 | /// Resolves the specified application server.
13 | ///
14 | /// The application server.
15 | /// The export provider.
16 | ///
17 | bool Resolve(IAppServer appServer, ExportProvider exportProvider);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/NRack.Base/IManagedApp.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using NRack.Base.Config;
3 | using NRack.Base.Metadata;
4 |
5 | namespace NRack.Base
6 | {
7 | public interface IManagedApp : IManagedAppBase
8 | {
9 | string Name { get; }
10 |
11 | bool Setup(IBootstrap bootstrap, IServerConfig config);
12 |
13 | ServerState State { get; }
14 |
15 | IServerConfig Config { get; }
16 | }
17 |
18 | public interface IManagedAppBase
19 | {
20 | AppServerMetadata GetMetadata();
21 |
22 | bool Start();
23 |
24 | void Stop();
25 |
26 | bool CanBeRecycled();
27 |
28 | StatusInfoCollection CollectStatus();
29 |
30 | void ReportPotentialConfigChange(IServerConfig config);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/NRack.Base/IMessageBus.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NRack.Base
4 | {
5 | ///
6 | /// NRack message bus interface
7 | ///
8 | public interface IMessageBus
9 | {
10 | ///
11 | /// Sends message of one specific topic to the specific receiver.
12 | ///
13 | /// The receiver.
14 | /// The topic.
15 | /// The message.
16 | void Send(IAppEndPoint receiver, string topic, object message);
17 |
18 | ///
19 | /// Sends message of one specific topic to global system.
20 | ///
21 | /// The topic.
22 | /// The message.
23 | void Send(string topic, object message);
24 |
25 | ///
26 | /// Register the topic message handler.
27 | ///
28 | ///
29 | /// The toppic.
30 | /// The topic handler.
31 | void On(string toppic, Action topicHandler);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/NRack.Base/IStatusCollector.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | #if DOTNETCORE
4 | using ILog = Microsoft.Extensions.Logging.ILogger;
5 | #else
6 | using AnyLog;
7 | #endif
8 |
9 | namespace NRack.Base
10 | {
11 | public class AppServerStatus
12 | {
13 | public AppServerMetadata Metadata { get; private set; }
14 |
15 | public StatusInfoCollection DataCollection { get; private set; }
16 |
17 | public AppServerStatus(AppServerMetadata metadata, StatusInfoCollection dataCollection)
18 | {
19 | Metadata = metadata;
20 | DataCollection = dataCollection;
21 | }
22 | }
23 |
24 | public interface IStatusCollector
25 | {
26 | void Collect(AppServerStatus bootstrapStatus, IEnumerable appStatusList, ILog logger);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/NRack.Base/IsolationMode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NRack.Base
4 | {
5 | ///
6 | /// AppServer instance running isolation mode
7 | ///
8 | public enum IsolationMode
9 | {
10 | ///
11 | /// No isolation
12 | ///
13 | None,
14 | ///
15 | /// Isolation by AppDomain
16 | ///
17 | AppDomain,
18 |
19 | ///
20 | /// Isolation by process
21 | ///
22 | Process
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/NRack.Base/Metadata/AppServerMetadata.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Reflection;
4 | using System.Runtime.Serialization;
5 | using NRack.Base.Metadata;
6 |
7 | namespace NRack.Base
8 | {
9 | [Serializable]
10 | public class AppServerMetadata
11 | {
12 | public AppServerMetadata()
13 | {
14 |
15 | }
16 |
17 | public AppServerMetadata(IAppServerMetadata attribute, Type appType)
18 | {
19 | Name = attribute.Name;
20 | AppType = appType.AssemblyQualifiedName;
21 | StatusFields = StatusInfoAttribute.GetFromType(attribute.GetType()).ToArray();
22 | }
23 |
24 | public static AppServerMetadata GetAppServerMetadata(Type serverType)
25 | {
26 | if (serverType == null)
27 | throw new ArgumentNullException("serverType");
28 |
29 | var topType = serverType;
30 |
31 | var attType = typeof(AppServerMetadataAttribute);
32 |
33 | while (true)
34 | {
35 | var atts = serverType.GetCustomAttributes(attType, false);
36 |
37 | if (atts != null && atts.Length > 0)
38 | {
39 | var metatdata = atts[0] as AppServerMetadataAttribute;
40 | return new AppServerMetadata(metatdata, topType);
41 | }
42 |
43 | var baseType = serverType.GetBaseType();
44 |
45 | if (baseType == null)
46 | return null;
47 |
48 | serverType = baseType;
49 | }
50 | }
51 |
52 | #region IAppServerMetadata implementation
53 |
54 | public string Name { get; set; }
55 |
56 | public string AppType { get; set; }
57 |
58 | public StatusInfoAttribute[] StatusFields { get; set; }
59 |
60 | #endregion
61 | }
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/src/NRack.Base/Metadata/AppServerMetadataAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.Serialization;
4 | #if DOTNETCORE
5 | using System.Composition;
6 | #else
7 | using System.ComponentModel.Composition;
8 | #endif
9 |
10 |
11 | namespace NRack.Base.Metadata
12 | {
13 | [Serializable]
14 | [MetadataAttribute]
15 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
16 | [StatusInfo(StatusInfoKeys.IsRunning, Name = "Is Running", DataType = typeof(bool), Order = 100)]
17 | public class AppServerMetadataAttribute : ExportAttribute, IAppServerMetadata
18 | {
19 | public string Name { get; set; }
20 |
21 | public AppServerMetadataAttribute()
22 | : base(typeof(IAppServer))
23 | {
24 |
25 | }
26 |
27 | public AppServerMetadataAttribute(string name)
28 | : this()
29 | {
30 | Name = name;
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/NRack.Base/Metadata/IAppServerMetadata.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 |
4 | namespace NRack.Base.Metadata
5 | {
6 | public interface IAppServerMetadata
7 | {
8 | string Name { get; }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/NRack.Base/Metadata/StatusInfoAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.Serialization;
4 | using System.Linq;
5 | using System.Reflection;
6 |
7 | namespace NRack.Base.Metadata
8 | {
9 | ///
10 | /// StatusInfo Metadata
11 | ///
12 | #if !SILVERLIGHT
13 | [Serializable]
14 | #endif
15 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
16 | public class StatusInfoAttribute : Attribute
17 | {
18 | ///
19 | /// Initializes a new instance of the class.
20 | ///
21 | public StatusInfoAttribute()
22 | {
23 | OutputInLog = true;
24 | }
25 |
26 | ///
27 | /// Initializes a new instance of the class.
28 | ///
29 | /// The key.
30 | public StatusInfoAttribute(string key)
31 | : this()
32 | {
33 | Key = key;
34 | }
35 |
36 | ///
37 | /// Gets or sets the key.
38 | ///
39 | ///
40 | /// The key.
41 | ///
42 | public string Key { get; set; }
43 |
44 | ///
45 | /// Gets or sets the name.
46 | ///
47 | ///
48 | /// The name.
49 | ///
50 | public string Name { get; set; }
51 |
52 | ///
53 | /// Gets or sets the short name.
54 | ///
55 | ///
56 | /// The short name.
57 | ///
58 | public string ShortName { get; set; }
59 |
60 | ///
61 | /// Gets or sets the format.
62 | ///
63 | ///
64 | /// The format.
65 | ///
66 | public string Format { get; set; }
67 |
68 | ///
69 | /// Gets or sets the order.
70 | ///
71 | ///
72 | /// The order.
73 | ///
74 | public int Order { get; set; }
75 |
76 |
77 | ///
78 | /// Gets or sets a value indicating whether [output in log].
79 | ///
80 | ///
81 | /// true if [output in log]; otherwise, false.
82 | ///
83 | public bool OutputInLog { get; set; }
84 |
85 | ///
86 | /// Gets or sets the type of the data.
87 | ///
88 | ///
89 | /// The type of the data.
90 | ///
91 | public Type DataType { get; set; }
92 |
93 | public static IEnumerable GetFromType(Type type)
94 | {
95 | return type.GetCustomAttributes(typeof(StatusInfoAttribute), true).OfType();
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/NRack.Base/Metadata/StatusInfoKeys.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace NRack.Base.Metadata
7 | {
8 | ///
9 | /// Server StatusInfo Metadata
10 | ///
11 | public class StatusInfoKeys
12 | {
13 | #region Shared
14 |
15 | ///
16 | /// The cpu usage
17 | ///
18 | public const string CpuUsage = "CpuUsage";
19 |
20 | ///
21 | /// The memory usage
22 | ///
23 | public const string MemoryUsage = "MemoryUsage";
24 |
25 | ///
26 | /// The total thread count
27 | ///
28 | public const string TotalThreadCount = "TotalThreadCount";
29 |
30 | ///
31 | /// The available working threads count
32 | ///
33 | public const string AvailableWorkingThreads = "AvailableWorkingThreads";
34 |
35 | ///
36 | /// The available completion port threads count
37 | ///
38 | public const string AvailableCompletionPortThreads = "AvailableCompletionPortThreads";
39 |
40 | ///
41 | /// The max working threads count
42 | ///
43 | public const string MaxWorkingThreads = "MaxWorkingThreads";
44 |
45 | ///
46 | /// The max completion port threads count
47 | ///
48 | public const string MaxCompletionPortThreads = "MaxCompletionPortThreads";
49 |
50 | #endregion
51 |
52 | #region For server instance
53 | ///
54 | /// true if this instance is running; otherwise, false.
55 | ///
56 | public const string IsRunning = "IsRunning";
57 |
58 | #endregion
59 |
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/NRack.Base/NRack.Base.Net45.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {406671C6-5DCB-4B23-BD28-FB02C235EAE4}
8 | Library
9 | Properties
10 | NRack.Base
11 | NRack.Base
12 | v4.5
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\net45\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 | false
25 |
26 |
27 | pdbonly
28 | true
29 | bin\net45\Release\
30 | TRACE
31 | prompt
32 | 4
33 | false
34 |
35 |
36 |
37 | ..\packages\AnyLog.0.1.8\lib\net45\AnyLog.dll
38 | True
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | GlobalAssemblyInfo.cs
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
101 |
--------------------------------------------------------------------------------
/src/NRack.Base/NRack.Base.NetCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard1.3
5 | NRack.Base
6 | Library
7 | NRack.Base
8 | $(PackageTargetFallback);portable-net45+win8
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | $(DefineConstants);DOTNETCORE
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/NRack.Base/NRack.Base.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {406671C6-5DCB-4B23-BD28-FB02C235EAE4}
8 | Library
9 | Properties
10 | NRack.Base
11 | NRack.Base
12 | v4.0
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\net40\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\net40\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 | ..\packages\AnyLog.0.1.8\lib\net40\AnyLog.dll
36 | True
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | GlobalAssemblyInfo.cs
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
99 |
--------------------------------------------------------------------------------
/src/NRack.Base/NRack.Base.csproj.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | NDock.Base.csproj
5 | 1.0.0
6 | Kerry
7 | Kerry
8 | http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE
9 | http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE
10 | http://ICON_URL_HERE_OR_DELETE_THIS_LINE
11 | false
12 | Package description
13 | Summary of changes made in this release of the package.
14 | Copyright 2015
15 | Tag1 Tag2
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/NRack.Base/NRackEnv.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NRack.Base
4 | {
5 | ///
6 | /// System environment variables of NRack
7 | ///
8 | public static class NRackEnv
9 | {
10 | ///
11 | /// Is this runtime Mono
12 | ///
13 | public static readonly bool IsMono;
14 |
15 | static NRackEnv()
16 | {
17 | // detect the runtime by the type Mono.Runtime
18 | IsMono = Type.GetType("Mono.Runtime") != null;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/NRack.Base/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("NRack.Base")]
9 | [assembly: AssemblyDescription("NRack.Base")]
10 | [assembly: AssemblyConfiguration("")]
11 |
12 | // Setting ComVisible to false makes the types in this assembly not visible
13 | // to COM components. If you need to access a type in this assembly from
14 | // COM, set the ComVisible attribute to true on that type.
15 | [assembly: ComVisible(false)]
16 |
17 | // The following GUID is for the ID of the typelib if this project is exposed to COM
18 | [assembly: Guid("c9a0102b-2f59-4299-839c-bae1c3a02b93")]
19 |
--------------------------------------------------------------------------------
/src/NRack.Base/Provider/IProviderMetadata.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NRack.Base.Provider
4 | {
5 | ///
6 | /// The provider metadata interface
7 | ///
8 | public interface IProviderMetadata
9 | {
10 | ///
11 | /// Gets the name.
12 | ///
13 | ///
14 | /// The name.
15 | ///
16 | string Name { get; }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/NRack.Base/Provider/ProviderMetadataAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | #if DOTNETCORE
3 | using System.Composition;
4 | #else
5 | using System.ComponentModel.Composition;
6 | #endif
7 |
8 | namespace NRack.Base.Provider
9 | {
10 | [MetadataAttribute]
11 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
12 | public class ProviderMetadataAttribute : ExportAttribute, IProviderMetadata
13 | {
14 | public string Name { get; private set; }
15 |
16 | public ProviderMetadataAttribute(string name)
17 | {
18 | Name = name;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/NRack.Base/ServerState.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 |
4 | namespace NRack.Base
5 | {
6 | ///
7 | /// Server's state enum class
8 | ///
9 | public enum ServerState : int
10 | {
11 | ///
12 | /// Not initialized
13 | ///
14 | NotInitialized = ServerStateConst.NotInitialized,
15 |
16 | ///
17 | /// In initializing
18 | ///
19 | Initializing = ServerStateConst.Initializing,
20 |
21 | ///
22 | /// Has been initialized, but not started
23 | ///
24 | NotStarted = ServerStateConst.NotStarted,
25 |
26 | ///
27 | /// In starting
28 | ///
29 | Starting = ServerStateConst.Starting,
30 |
31 | ///
32 | /// In running
33 | ///
34 | Running = ServerStateConst.Running,
35 |
36 | ///
37 | /// In stopping
38 | ///
39 | Stopping = ServerStateConst.Stopping,
40 | }
41 |
42 | internal class ServerStateConst
43 | {
44 | public const int NotInitialized = 0;
45 |
46 | public const int Initializing = 1;
47 |
48 | public const int NotStarted = 2;
49 |
50 | public const int Starting = 3;
51 |
52 | public const int Running = 4;
53 |
54 | public const int Stopping = 5;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/NRack.Base/StartupType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 |
4 | namespace NRack.Base
5 | {
6 | ///
7 | /// Startup type
8 | ///
9 | public enum StartupType
10 | {
11 | ///
12 | /// Automatic
13 | ///
14 | Automatic,
15 |
16 | ///
17 | /// Manual
18 | ///
19 | Manual,
20 |
21 | ///
22 | /// Disabled
23 | ///
24 | Disabled
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/NRack.Base/StatusInfoCollection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.Serialization;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace NRack.Base
9 | {
10 | ///
11 | /// Status information collection
12 | ///
13 | [Serializable]
14 | public class StatusInfoCollection
15 | {
16 | public StatusInfoCollection()
17 | {
18 |
19 | }
20 |
21 | public StatusInfoCollection(string name)
22 | : this(name, name)
23 | {
24 |
25 | }
26 |
27 | public StatusInfoCollection(string name, string tag)
28 | {
29 | Name = name;
30 | Tag = tag;
31 | }
32 |
33 | [NonSerialized]
34 | private Dictionary m_Values = new Dictionary();
35 |
36 |
37 | ///
38 | /// Gets the values.
39 | ///
40 | ///
41 | /// The values.
42 | ///
43 | public Dictionary Values
44 | {
45 | get { return m_Values; }
46 | }
47 |
48 | ///
49 | /// Gets or sets the name.
50 | ///
51 | ///
52 | /// The name.
53 | ///
54 | public string Name { get; set; }
55 |
56 |
57 | ///
58 | /// Gets or sets the tag.
59 | ///
60 | ///
61 | /// The tag.
62 | ///
63 | public string Tag { get; set; }
64 |
65 | ///
66 | /// Gets or sets the started time.
67 | ///
68 | ///
69 | /// The started time.
70 | ///
71 | public DateTime? StartedTime { get; set; }
72 |
73 | ///
74 | /// Gets or sets the collected time.
75 | ///
76 | ///
77 | /// The collected time.
78 | ///
79 | public DateTime CollectedTime { get; set; }
80 |
81 | ///
82 | /// Gets or sets the with the specified name.
83 | ///
84 | ///
85 | /// The .
86 | ///
87 | /// The name.
88 | ///
89 | public object this[string name]
90 | {
91 | get
92 | {
93 | object value;
94 |
95 | if (m_Values.TryGetValue(name, out value))
96 | return value;
97 |
98 | return null;
99 | }
100 | set
101 | {
102 | m_Values[name] = value;
103 | }
104 | }
105 |
106 | ///
107 | /// Gets the value.
108 | ///
109 | ///
110 | /// The name.
111 | /// The default value.
112 | ///
113 | public T GetValue(string name, T defaultValue)
114 | where T : struct
115 | {
116 | object value;
117 |
118 | if (m_Values.TryGetValue(name, out value))
119 | return (T)value;
120 |
121 | return defaultValue;
122 | }
123 |
124 | private List> m_InternalList;
125 |
126 | [OnSerializing]
127 | private void OnSerializing(StreamingContext context)
128 | {
129 | m_InternalList = new List>(m_Values.Count);
130 |
131 | foreach (var entry in m_Values)
132 | {
133 | m_InternalList.Add(new KeyValuePair(entry.Key, entry.Value));
134 | }
135 | }
136 |
137 | [OnDeserialized]
138 | private void OnDeserialized(StreamingContext context)
139 | {
140 | if (m_InternalList == null || m_InternalList.Count <= 0)
141 | return;
142 |
143 | if (m_Values == null)
144 | m_Values = new Dictionary();
145 |
146 | foreach (var entry in m_InternalList)
147 | {
148 | m_Values.Add(entry.Key, entry.Value);
149 | }
150 |
151 | m_InternalList = null;
152 | }
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/NRack.Base/packages.NRack.Base.Net45.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/NRack.Base/packages.NRack.Base.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/NRack.Server/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/NRack.Server/BootstrapFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Linq;
5 | using System.Text;
6 | using NRack.Base;
7 | using NRack.Base.Config;
8 | using NRack.Server.Isolation.AppDomainIsolation;
9 | using NRack.Server.Isolation.ProcessIsolation;
10 |
11 | namespace NRack.Server
12 | {
13 | ///
14 | /// Bootstrap Factory
15 | ///
16 | public static class BootstrapFactory
17 | {
18 | ///
19 | /// Creates the bootstrap.
20 | ///
21 | /// The config.
22 | ///
23 | public static IBootstrap CreateBootstrap(IConfigSource config)
24 | {
25 | if (config == null)
26 | throw new ArgumentNullException("config");
27 |
28 | if (config.Isolation == IsolationMode.AppDomain)
29 | return new AppDomainBootstrap(config);
30 | else if (config.Isolation == IsolationMode.Process)
31 | return new ProcessBootstrap(config);
32 | else
33 | return new DefaultBootstrap(config);
34 | }
35 |
36 | ///
37 | /// Creates the bootstrap from app configuration's socketServer section.
38 | ///
39 | ///
40 | public static IBootstrap CreateBootstrap()
41 | {
42 | var configSection = ConfigurationManager.GetSection("nrack");
43 |
44 | if (configSection == null)
45 | throw new ConfigurationErrorsException("Missing 'nrack' configuration section.");
46 |
47 | var configSource = configSection as IConfigSource;
48 | if (configSource == null)
49 | throw new ConfigurationErrorsException("Invalid 'nrack' configuration section.");
50 |
51 | return CreateBootstrap(configSource);
52 | }
53 |
54 | ///
55 | /// Creates the bootstrap from configuration file.
56 | ///
57 | /// The configuration file.
58 | ///
59 | public static IBootstrap CreateBootstrapFromConfigFile(string configFile)
60 | {
61 | ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
62 | fileMap.ExeConfigFilename = configFile;
63 |
64 | var config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
65 |
66 | var configSection = config.GetSection("nrack");
67 |
68 | if (configSection == null)
69 | throw new ConfigurationErrorsException("Missing 'nrack' configuration section.");
70 |
71 | var configSource = configSection as IConfigSource;
72 | if (configSource == null)
73 | throw new ConfigurationErrorsException("Invalid 'nrack' configuration section.");
74 |
75 | return CreateBootstrap(configSource);
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/NRack.Server/Config/log4net.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/src/NRack.Server/Config/nlog.config:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
17 |
23 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/NRack.Server/ConfigurationWatcher.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.IO;
5 | using System.Linq;
6 | using AnyLog;
7 | using NRack.Base;
8 | using NRack.Base.Config;
9 |
10 | namespace NRack.Server
11 | {
12 | ///
13 | /// The configuration file watcher, it is used for hot configuration updating
14 | ///
15 | public static class ConfigurationWatcher
16 | {
17 | private static FileSystemWatcher m_Watcher;
18 |
19 | private static DateTime m_LastUpdatedTime;
20 |
21 | ///
22 | /// Watches the specified configuration section.
23 | ///
24 | /// The configuration section.
25 | /// The bootstrap.
26 | public static void Watch(ConfigurationSection configSection, IBootstrap bootstrap)
27 | {
28 | if (configSection == null)
29 | throw new ArgumentNullException("configSection");
30 |
31 | if (bootstrap == null)
32 | throw new ArgumentNullException("bootstrap");
33 |
34 | var sectionName = configSection.SectionInformation.Name;
35 |
36 | var configSourceFile = bootstrap.ConfigFilePath;
37 |
38 | if (string.IsNullOrEmpty(configSourceFile))
39 | throw new Exception("Cannot get your configuration file's location.");
40 |
41 | m_Watcher = new FileSystemWatcher(Path.GetDirectoryName(configSourceFile), Path.GetFileName(configSourceFile));
42 | m_Watcher.IncludeSubdirectories = false;
43 | m_Watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size;
44 | m_Watcher.Changed += (s, e) =>
45 | {
46 | var filePath = e.FullPath;
47 |
48 | if (!NeedsLoadConfig(filePath))
49 | return;
50 |
51 | lock (m_Watcher)
52 | {
53 | if (!NeedsLoadConfig(filePath))
54 | return;
55 |
56 | OnConfigFileUpdated(filePath, sectionName, bootstrap);
57 | m_LastUpdatedTime = DateTime.Now;
58 | }
59 | };
60 |
61 | m_Watcher.EnableRaisingEvents = true;
62 | }
63 |
64 | internal static void Pause()
65 | {
66 | m_Watcher.EnableRaisingEvents = false;
67 | }
68 |
69 | internal static void Resume()
70 | {
71 | m_Watcher.EnableRaisingEvents = true;
72 | }
73 |
74 | private static bool NeedsLoadConfig(string filePath)
75 | {
76 | return File.GetLastWriteTime(filePath) > m_LastUpdatedTime;
77 | }
78 |
79 | private static void OnConfigFileUpdated(string filePath, string sectionName, IBootstrap bootstrap)
80 | {
81 | var fileMap = new ExeConfigurationFileMap();
82 | fileMap.ExeConfigFilename = filePath;
83 |
84 | System.Configuration.Configuration config;
85 |
86 | try
87 | {
88 | config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
89 | }
90 | catch(Exception e)
91 | {
92 | var loggerProvider = bootstrap as ILoggerProvider;
93 |
94 | if (loggerProvider != null)
95 | {
96 | var logger = loggerProvider.Logger;
97 |
98 | if (logger != null)
99 | logger.Error("Configuraton loading error.", e);
100 | }
101 |
102 | return;
103 | }
104 |
105 | var configSource = config.GetSection(sectionName) as IConfigSource;
106 |
107 | if (configSource == null)
108 | return;
109 |
110 | foreach (var serverConfig in configSource.Servers)
111 | {
112 | var server = bootstrap.AppServers.FirstOrDefault(x =>
113 | x.Name.Equals(serverConfig.Name, StringComparison.OrdinalIgnoreCase));
114 |
115 | if (server == null)
116 | continue;
117 |
118 | server.ReportPotentialConfigChange(new ServerConfig(serverConfig));
119 | }
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/NRack.Server/ControlCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using NRack.Base;
6 |
7 | namespace NRack.Server
8 | {
9 | class ControlCommand
10 | {
11 | public string Name { get; set; }
12 |
13 | public string Description { get; set; }
14 |
15 | public Func Handler { get; set; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/NRack.Server/DefaultBootstrap.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.Composition.Hosting;
4 | using System.Linq;
5 | using System.Text;
6 | using NRack.Base;
7 | using NRack.Base.Config;
8 | using NRack.Base.Metadata;
9 |
10 | namespace NRack.Server
11 | {
12 | [StatusInfo(StatusInfoKeys.CpuUsage, Name = "CPU Usage", Format = "{0:0.00}%", DataType = typeof(double), Order = 112)]
13 | [StatusInfo(StatusInfoKeys.MemoryUsage, Name = "Physical Memory Usage", Format = "{0:N}", DataType = typeof(double), Order = 113)]
14 | [StatusInfo(StatusInfoKeys.TotalThreadCount, Name = "Total Thread Count", Format = "{0}", DataType = typeof(double), Order = 114)]
15 | [StatusInfo(StatusInfoKeys.AvailableWorkingThreads, Name = "Available Working Threads", Format = "{0}", DataType = typeof(double), Order = 512)]
16 | [StatusInfo(StatusInfoKeys.AvailableCompletionPortThreads, Name = "Available Completion Port Threads", Format = "{0}", DataType = typeof(double), Order = 513)]
17 | [StatusInfo(StatusInfoKeys.MaxWorkingThreads, Name = "Maximum Working Threads", Format = "{0}", DataType = typeof(double), Order = 513)]
18 | [StatusInfo(StatusInfoKeys.MaxCompletionPortThreads, Name = "Maximum Completion Port Threads", Format = "{0}", DataType = typeof(double), Order = 514)]
19 | public class DefaultBootstrap : BootstrapBase
20 | {
21 | public DefaultBootstrap(IConfigSource configSource)
22 | : base(configSource)
23 | {
24 |
25 | }
26 |
27 | protected override IManagedApp CreateAppInstanceByMetadata(AppServerMetadata metadata)
28 | {
29 | return (IManagedApp)Activator.CreateInstance(Type.GetType(metadata.AppType, true, true));
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/NRack.Server/DefaultStatusCollector.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.Composition;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using AnyLog;
8 | using NRack.Base;
9 | using NRack.Base.Provider;
10 |
11 | namespace NRack.Server
12 | {
13 | [Export(typeof(IStatusCollector))]
14 | [ProviderMetadata("DefaultStatusCollector")]
15 | class DefaultStatusCollector : IStatusCollector
16 | {
17 | private void CollectAppServer(AppServerStatus app, StringBuilder sb)
18 | {
19 | var meta = app.Metadata;
20 | var status = app.DataCollection;
21 |
22 | sb.AppendLine(string.Format("{0} ----------------------------------", status.Name));
23 |
24 | foreach (var info in meta.StatusFields)
25 | {
26 | var infoValue = status[info.Key];
27 |
28 | if (infoValue == null)
29 | continue;
30 |
31 | sb.AppendLine(string.Format("{0}: {1}", info.Name,
32 | string.IsNullOrEmpty(info.Format) ? infoValue : string.Format(info.Format, infoValue)));
33 | }
34 | }
35 |
36 | public void Collect(AppServerStatus bootstrapStatus, IEnumerable appStatusList, ILog logger)
37 | {
38 | var sb = new StringBuilder();
39 |
40 | CollectAppServer(bootstrapStatus, sb);
41 |
42 | foreach (var app in appStatusList)
43 | {
44 | CollectAppServer(app, sb);
45 | }
46 |
47 | logger.Info(sb.ToString());
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/NRack.Server/IRemoteManagedApp.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using NRack.Base;
6 | using NRack.Base.Config;
7 |
8 | namespace NRack.Server
9 | {
10 | ///
11 | /// IRemoteManagedApp
12 | ///
13 | public interface IRemoteManagedApp : IManagedAppBase
14 | {
15 | ///
16 | /// Setups with the specified config.
17 | ///
18 | /// Type of the server.
19 | /// The bootstrap URI.
20 | /// The assembly import root.
21 | /// The config.
22 | /// The startup configuration file path.
23 | ///
24 | bool Setup(string serverType, string bootstrapUri, string assemblyImportRoot, IServerConfig config, string startupConfigFile);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/NRack.Server/Isolation/AppAssemblyUpdateState.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace NRack.Server.Isolation
9 | {
10 | class AppAssemblyUpdateState
11 | {
12 | public DateTime CurrentAssemblyTime { get; private set; }
13 |
14 | public DateTime LastUpdatedTime { get; private set; }
15 |
16 | public DateTime LastCheckTime { get; set; }
17 |
18 | private string m_AppAssemblyDir;
19 |
20 | public AppAssemblyUpdateState(string dir)
21 | {
22 | m_AppAssemblyDir = dir;
23 | CurrentAssemblyTime = LastUpdatedTime = GetLastUpdateTime();
24 | }
25 |
26 | private DateTime GetLastUpdateTime()
27 | {
28 | var lastUpdatedTime = DateTime.MinValue;
29 |
30 | foreach(var file in Directory.GetFiles(m_AppAssemblyDir, "*.dll").Union(Directory.GetFiles(m_AppAssemblyDir, "*.exe")))
31 | {
32 | var fileWriteTime = File.GetLastWriteTime(file);
33 |
34 | if (fileWriteTime > lastUpdatedTime)
35 | lastUpdatedTime = fileWriteTime;
36 | }
37 |
38 | return lastUpdatedTime;
39 | }
40 |
41 | public bool TryCheckUpdate()
42 | {
43 | var lastUpdatedTime = GetLastUpdateTime();
44 |
45 | if (lastUpdatedTime <= LastUpdatedTime)
46 | return false;
47 |
48 | LastUpdatedTime = lastUpdatedTime;
49 | LastCheckTime = DateTime.Now;
50 | return true;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/NRack.Server/Isolation/AppDomainIsolation/AppDomainApp.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.IO;
6 | using System.Reflection;
7 | using System.Threading.Tasks;
8 | using NRack.Base;
9 | using NRack.Base.Config;
10 | using NRack.Base.Metadata;
11 | using NRack.Server.Isolation;
12 | using System.Diagnostics;
13 |
14 | namespace NRack.Server.Isolation.AppDomainIsolation
15 | {
16 | [StatusInfo(StatusInfoKeys.CpuUsage, Name = "CPU Usage", Format = "{0:0.00}%", DataType = typeof(double), Order = 112)]
17 | [StatusInfo(StatusInfoKeys.MemoryUsage, Name = "Memory Usage", Format = "{0:N}", DataType = typeof(double), Order = 113)]
18 | class AppDomainApp : IsolationApp
19 | {
20 | private AppDomain m_HostDomain;
21 |
22 | private readonly static bool m_AppDomainMonitoringSupported = false;
23 |
24 | static AppDomainApp()
25 | {
26 | try
27 | {
28 | AppDomain.MonitoringIsEnabled = true;
29 | m_AppDomainMonitoringSupported = true;
30 | }
31 | catch (NotImplementedException)
32 | {
33 | return;
34 | }
35 | }
36 |
37 | public AppDomainApp(AppServerMetadata metadata, string startupConfigFile)
38 | : base(metadata, startupConfigFile)
39 | {
40 |
41 | }
42 |
43 | private AppDomain CreateHostAppDomain()
44 | {
45 | var currentDomain = AppDomain.CurrentDomain;
46 |
47 | var startupConfigFile = StartupConfigFile;
48 |
49 | if (!string.IsNullOrEmpty(startupConfigFile))
50 | {
51 | if (!Path.IsPathRooted(startupConfigFile))
52 | startupConfigFile = Path.Combine(currentDomain.BaseDirectory, startupConfigFile);
53 | }
54 |
55 | var setupInfo = new AppDomainSetup
56 | {
57 | ApplicationName = Name,
58 | ApplicationBase = AppWorkingDir,
59 | ConfigurationFile = startupConfigFile,
60 | ShadowCopyFiles = "true",
61 | CachePath = Path.Combine(currentDomain.BaseDirectory, IsolationAppConst.ShadowCopyDir)
62 | };
63 |
64 | var hostAppDomain = AppDomain.CreateDomain(Name, currentDomain.Evidence, setupInfo);
65 |
66 | var assemblyImportType = typeof(AssemblyImport);
67 |
68 | hostAppDomain.CreateInstanceFrom(assemblyImportType.Assembly.CodeBase,
69 | assemblyImportType.FullName,
70 | true,
71 | BindingFlags.CreateInstance,
72 | null,
73 | new object[] { currentDomain.BaseDirectory },
74 | null,
75 | new object[0]);
76 |
77 | return hostAppDomain;
78 | }
79 |
80 | protected override IManagedAppBase CreateAndStartServerInstance()
81 | {
82 | IManagedApp appServer;
83 |
84 | try
85 | {
86 | m_HostDomain = CreateHostAppDomain();
87 |
88 | m_HostDomain.SetData(typeof(IsolationMode).Name, IsolationMode.AppDomain);
89 |
90 | var marshalServerType = typeof(MarshalManagedApp);
91 |
92 | appServer = (IManagedApp)m_HostDomain.CreateInstanceAndUnwrap(marshalServerType.Assembly.FullName,
93 | marshalServerType.FullName,
94 | true,
95 | BindingFlags.CreateInstance,
96 | null,
97 | new object[] { GetMetadata().AppType },
98 | null,
99 | new object[0]);
100 |
101 | if (!appServer.Setup(Bootstrap, Config))
102 | {
103 | OnExceptionThrown(new Exception("Failed to setup MarshalManagedApp"));
104 | return null;
105 | }
106 |
107 | if (!appServer.Start())
108 | {
109 | OnExceptionThrown(new Exception("Failed to start MarshalManagedApp"));
110 | return null;
111 | }
112 |
113 | m_HostDomain.DomainUnload += new EventHandler(m_HostDomain_DomainUnload);
114 |
115 | return appServer;
116 | }
117 | catch (Exception e)
118 | {
119 | if (m_HostDomain != null)
120 | {
121 | AppDomain.Unload(m_HostDomain);
122 | m_HostDomain = null;
123 | }
124 |
125 | OnExceptionThrown(e);
126 | return null;
127 | }
128 | }
129 |
130 | protected override void Stop()
131 | {
132 | if (m_HostDomain != null)
133 | {
134 | AppDomain.Unload(m_HostDomain);
135 | }
136 | }
137 |
138 |
139 | void m_HostDomain_DomainUnload(object sender, EventArgs e)
140 | {
141 | m_HostDomain = null;
142 | OnStopped();
143 | }
144 |
145 | protected override StatusInfoCollection CollectStatus()
146 | {
147 | var app = ManagedApp;
148 |
149 | if (app == null)
150 | return null;
151 |
152 | var status = app.CollectStatus();
153 |
154 | if(m_AppDomainMonitoringSupported)
155 | {
156 | status[StatusInfoKeys.MemoryUsage] = m_HostDomain == null ? 0 : m_HostDomain.MonitoringSurvivedMemorySize;
157 |
158 | var process = Process.GetCurrentProcess();
159 | var value = m_HostDomain.MonitoringTotalProcessorTime.TotalMilliseconds * 100 / process.TotalProcessorTime.TotalMilliseconds;
160 | status[StatusInfoKeys.CpuUsage] = value;
161 | }
162 |
163 | return status;
164 | }
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/src/NRack.Server/Isolation/AppDomainIsolation/AppDomainBootstrap.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Configuration;
6 | using NRack.Base;
7 | using NRack.Base.Config;
8 | using NRack.Base.Configuration;
9 | using NRack.Base.Metadata;
10 | using NRack.Server.Isolation;
11 |
12 | namespace NRack.Server.Isolation.AppDomainIsolation
13 | {
14 | class AppDomainBootstrap : IsolationBootstrap
15 | {
16 | public AppDomainBootstrap(IConfigSource configSource)
17 | : base(configSource)
18 | {
19 |
20 | }
21 |
22 | protected override IManagedApp CreateAppInstanceByMetadata(AppServerMetadata metadata)
23 | {
24 | return new AppDomainApp(metadata, ConfigFilePath);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/NRack.Server/Isolation/AssemblyImport.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Reflection;
6 | using System.Text;
7 |
8 | namespace NRack.Server.Isolation
9 | {
10 | ///
11 | /// AssemblyImport, used for importing assembly to the current AppDomain
12 | ///
13 | public class AssemblyImport : MarshalByRefObject
14 | {
15 | private string m_ImportRoot;
16 |
17 | ///
18 | /// Initializes a new instance of the class.
19 | ///
20 | public AssemblyImport(string importRoot)
21 | {
22 | m_ImportRoot = importRoot;
23 | AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
24 | }
25 |
26 | //Process cannot resolved assemblies
27 | Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
28 | {
29 | AssemblyName name = new AssemblyName(args.Name);
30 |
31 | var assemblyFilePath = Path.Combine(m_ImportRoot, name.Name + ".dll");
32 |
33 | if(File.Exists(assemblyFilePath))
34 | return Assembly.LoadFrom(assemblyFilePath);
35 |
36 | assemblyFilePath = Path.Combine(m_ImportRoot, name.Name + ".exe");
37 |
38 | if (File.Exists(assemblyFilePath))
39 | return Assembly.LoadFrom(assemblyFilePath);
40 |
41 | assemblyFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, name.Name + ".dll");
42 |
43 | if (File.Exists(assemblyFilePath))
44 | return Assembly.LoadFrom(assemblyFilePath);
45 |
46 | assemblyFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, name.Name + ".exe");
47 |
48 | if (File.Exists(assemblyFilePath))
49 | return Assembly.LoadFrom(assemblyFilePath);
50 |
51 | return null;
52 | }
53 |
54 | ///
55 | /// Registers the assembply import.
56 | ///
57 | /// The host application domain.
58 | public static void RegisterAssembplyImport(AppDomain hostAppDomain)
59 | {
60 | var assemblyImportType = typeof(AssemblyImport);
61 |
62 | hostAppDomain.CreateInstanceFrom(assemblyImportType.Assembly.CodeBase,
63 | assemblyImportType.FullName,
64 | true,
65 | BindingFlags.CreateInstance,
66 | null,
67 | new object[] { AppDomain.CurrentDomain.BaseDirectory },
68 | null,
69 | new object[0]);
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/NRack.Server/Isolation/IsolationBootstrap.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Linq;
5 | using System.Text;
6 | using NRack.Base;
7 | using NRack.Base.Config;
8 | using NRack.Base.Configuration;
9 | using NRack.Base.Metadata;
10 | using NRack.Base.Provider;
11 | using NRack.Server.Config;
12 | using NRack.Server.Recycle;
13 |
14 | namespace NRack.Server.Isolation
15 | {
16 | [StatusInfo(StatusInfoKeys.CpuUsage, Name = "CPU Usage", Format = "{0:0.00}%", DataType = typeof(double), Order = 112)]
17 | [StatusInfo(StatusInfoKeys.MemoryUsage, Name = "Physical Memory Usage", Format = "{0:N}", DataType = typeof(double), Order = 113)]
18 | [StatusInfo(StatusInfoKeys.TotalThreadCount, Name = "Total Thread Count", Format = "{0}", DataType = typeof(double), Order = 114)]
19 | abstract class IsolationBootstrap : BootstrapBase
20 | {
21 |
22 | private IBootstrap m_RemoteBootstrapWrap;
23 |
24 | private IEnumerable> m_RecycleTriggers;
25 |
26 | public IsolationBootstrap(IConfigSource configSource)
27 | : base(GetSerializableConfigSource(configSource)) // make the configuration source serializable
28 | {
29 | HandleConfigSource(configSource);
30 | m_RemoteBootstrapWrap = new RemoteBootstrapProxy(this);
31 | m_RecycleTriggers = AppDomain.CurrentDomain.GetCurrentAppDomainExportProvider().GetExports();
32 | }
33 |
34 |
35 | private static IConfigSource GetSerializableConfigSource(IConfigSource configSource)
36 | {
37 | if (configSource.GetType().IsSerializable)
38 | {
39 | return configSource;
40 | }
41 |
42 | return new NRackConfig(configSource);
43 | }
44 |
45 | protected override AppServerMetadata GetAppServerMetadata(IServerConfig serverConfig)
46 | {
47 | AppDomain validateDomain = null;
48 | AppServerMetadata metadata = null;
49 |
50 | try
51 | {
52 | validateDomain = AppDomain.CreateDomain("ValidationDomain", AppDomain.CurrentDomain.Evidence, IsolationApp.GetAppWorkingDir(serverConfig), string.Empty, false);
53 |
54 | AssemblyImport.RegisterAssembplyImport(validateDomain);
55 |
56 | validateDomain.SetData(typeof(IsolationMode).Name, ConfigSource.Isolation);
57 |
58 | var validatorType = typeof(RemoteAppTypeValidator);
59 | var validator = (RemoteAppTypeValidator)validateDomain.CreateInstanceAndUnwrap(validatorType.Assembly.FullName, validatorType.FullName);
60 |
61 | var result = validator.GetServerMetadata(serverConfig.Type);
62 |
63 | if(!result.Result)
64 | {
65 | Logger.Error(result.Message);
66 | return null;
67 | }
68 |
69 | metadata = result.Value;
70 | }
71 | finally
72 | {
73 | if (validateDomain != null)
74 | AppDomain.Unload(validateDomain);
75 | }
76 |
77 | return metadata;
78 | }
79 |
80 | void SetupRecycleTriggers(IManagedApp managedApp, IServerConfig config)
81 | {
82 | try
83 | {
84 | var recycleTriggers = config.OptionElements.GetChildConfig("recycleTriggers");
85 |
86 | if (recycleTriggers == null || !recycleTriggers.Any())
87 | return;
88 |
89 | var triggers = new List();
90 |
91 | foreach (var triggerConfig in recycleTriggers)
92 | {
93 | var triggerType = m_RecycleTriggers.FirstOrDefault(t =>
94 | t.Metadata.Name.Equals(triggerConfig.Name, StringComparison.OrdinalIgnoreCase));
95 |
96 | if (triggerType == null)
97 | {
98 | Logger.ErrorFormat("We cannot find a RecycleTrigger with the name '{0}'.", triggerConfig.Name);
99 | continue;
100 | }
101 |
102 | var trigger = triggerType.Value;
103 |
104 | if (!trigger.Initialize(triggerConfig.Options))
105 | {
106 | Logger.ErrorFormat("Failed to initialize the RecycleTrigger '{0}'.", triggerConfig.Name);
107 | continue;
108 | }
109 |
110 | triggers.Add(trigger);
111 | }
112 |
113 | if (triggers.Any())
114 | {
115 | (managedApp as IsolationApp).RecycleTriggers = triggers.ToArray();
116 | }
117 | }
118 | catch (Exception e)
119 | {
120 | Logger.Error("Failed to load recycle triggers.", e);
121 | }
122 | }
123 |
124 | protected override bool Setup(IManagedApp managedApp, IServerConfig config)
125 | {
126 | var ret = managedApp.Setup(m_RemoteBootstrapWrap, config);
127 |
128 | if (!ret)
129 | return false;
130 |
131 | SetupRecycleTriggers(managedApp, config);
132 | return ret;
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/NRack.Server/Isolation/MarshalManagedApp.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using NRack.Base;
6 | using NRack.Base.Config;
7 | using NRack.Base.Metadata;
8 |
9 | namespace NRack.Server.Isolation
10 | {
11 | ///
12 | /// Marshal wrap for managed app instance
13 | /// We don't want to make the real app instance marshalable
14 | ///
15 | class MarshalManagedApp : MarshalByRefObject, IManagedApp
16 | {
17 | private IManagedApp m_ManagedApp;
18 |
19 | public MarshalManagedApp(string appTypeName)
20 | {
21 | var appType = Type.GetType(appTypeName);
22 | m_ManagedApp = (IManagedApp)Activator.CreateInstance(appType);
23 | }
24 |
25 | public string Name
26 | {
27 | get { return m_ManagedApp.Name; }
28 | }
29 |
30 | public bool Setup(IBootstrap bootstrap, IServerConfig config)
31 | {
32 | return m_ManagedApp.Setup(bootstrap, config);
33 | }
34 |
35 | public ServerState State
36 | {
37 | get { return m_ManagedApp.State; }
38 | }
39 |
40 | public IServerConfig Config
41 | {
42 | get { return m_ManagedApp.Config; }
43 | }
44 |
45 | public AppServerMetadata GetMetadata()
46 | {
47 | return m_ManagedApp.GetMetadata();
48 | }
49 |
50 | public bool Start()
51 | {
52 | return m_ManagedApp.Start();
53 | }
54 |
55 | public void Stop()
56 | {
57 | m_ManagedApp.Stop();
58 | }
59 |
60 | public bool CanBeRecycled()
61 | {
62 | return m_ManagedApp.CanBeRecycled();
63 | }
64 |
65 | public StatusInfoCollection CollectStatus()
66 | {
67 | return m_ManagedApp.CollectStatus();
68 | }
69 |
70 | public void ReportPotentialConfigChange(IServerConfig config)
71 | {
72 | m_ManagedApp.ReportPotentialConfigChange(config);
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/NRack.Server/Isolation/ProcessIsolation/ExternalProcessAppServerMetadata.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using NRack.Base;
7 |
8 | namespace NRack.Server.Isolation.ProcessIsolation
9 | {
10 | class ExternalProcessAppServerMetadata : AppServerMetadata
11 | {
12 | public ExternalProcessAppServerMetadata(string appDir, string appFile, string appArgs)
13 | {
14 | AppDir = appDir;
15 | AppFile = appFile;
16 | AppArgs = appArgs;
17 | }
18 |
19 | public string AppDir { get; private set; }
20 |
21 | public string AppFile { get; private set; }
22 |
23 | public string AppArgs { get; private set; }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/NRack.Server/Isolation/ProcessIsolation/ProcessBootstrap.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using NRack.Base;
6 | using NRack.Base.Config;
7 | using NRack.Base.Metadata;
8 | using NRack.Server.Isolation;
9 |
10 | namespace NRack.Server.Isolation.ProcessIsolation
11 | {
12 | class ProcessBootstrap : IsolationBootstrap
13 | {
14 | public ProcessBootstrap(IConfigSource configSource)
15 | : base(configSource)
16 | {
17 |
18 | }
19 |
20 | protected override IManagedApp CreateAppInstance(IServerConfig serverConfig)
21 | {
22 | var appFile = serverConfig.Options.Get("appFile");
23 |
24 | if(string.IsNullOrEmpty(appFile))
25 | return base.CreateAppInstance(serverConfig);
26 |
27 | var serverMetadata = new ExternalProcessAppServerMetadata(serverConfig.Options.Get("appDir"), appFile, serverConfig.Options.Get("appArgs"));
28 | return new ExternalProcessApp(serverMetadata, ConfigFilePath);
29 | }
30 |
31 | protected override IManagedApp CreateAppInstanceByMetadata(AppServerMetadata metadata)
32 | {
33 | return new ProcessApp(metadata, ConfigFilePath);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/NRack.Server/Isolation/ProcessIsolation/ProcessLocker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Reflection;
7 | using System.Text;
8 | using Microsoft.Win32.SafeHandles;
9 | using NRack.Base;
10 |
11 | namespace NRack.Server
12 | {
13 | class ProcessLocker
14 | {
15 | private string m_LockFilePath;
16 |
17 | public ProcessLocker(string workDir, string lockFileName)
18 | {
19 | m_LockFilePath = Path.Combine(workDir, lockFileName);
20 | }
21 |
22 | public Process GetLockedProcess()
23 | {
24 | if (!File.Exists(m_LockFilePath))
25 | return null;
26 |
27 | int processId;
28 |
29 | var lockFileText = File.ReadAllText(m_LockFilePath);
30 |
31 | var lockFileInfoArray = lockFileText.Split(',');
32 |
33 | if (!int.TryParse(lockFileInfoArray[0], out processId))
34 | {
35 | File.Delete(m_LockFilePath);
36 | return null;
37 | }
38 |
39 | try
40 | {
41 | var process = Process.GetProcessById(processId);
42 |
43 | var safeInputHandle = new SafeFileHandle(new IntPtr(long.Parse(lockFileInfoArray[1])), true);
44 |
45 | var standardInput = new StreamWriter(new FileStream(safeInputHandle, FileAccess.Write, 4096, false), Encoding.UTF8, 4096);
46 | standardInput.AutoFlush = true;
47 |
48 | var standInputFieldName = NRackEnv.IsMono ? "input_stream" : "standardInput";
49 |
50 | var standInputField = process.GetType().GetField(standInputFieldName,
51 | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.SetField | BindingFlags.GetField);
52 |
53 | standInputField.SetValue(process, standardInput);
54 |
55 | return process;
56 | }
57 | catch
58 | {
59 | File.Delete(m_LockFilePath);
60 | return null;
61 | }
62 | }
63 |
64 | public void SaveLock(Process process)
65 | {
66 | var inputHandle = (process.StandardInput.BaseStream as FileStream)
67 | .SafeFileHandle
68 | .DangerousGetHandle().ToInt64();
69 |
70 | File.WriteAllText(m_LockFilePath, string.Format("{0},{1}", process.Id, inputHandle));
71 | }
72 |
73 | public void CleanLock()
74 | {
75 | if (File.Exists(m_LockFilePath))
76 | File.Delete(m_LockFilePath);
77 | }
78 |
79 | ~ProcessLocker()
80 | {
81 | CleanLock();
82 | }
83 | }
84 | }
85 |
86 |
--------------------------------------------------------------------------------
/src/NRack.Server/MefExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.Composition;
4 | using System.ComponentModel.Composition.Primitives;
5 | using System.ComponentModel.Composition.ReflectionModel;
6 | using System.Linq;
7 | using System.Reflection;
8 | using System.Text;
9 |
10 | namespace NRack.Server
11 | {
12 | public static class MefExtensions
13 | {
14 | public static Type GetExportType(this Lazy lazyFactory)
15 | {
16 | var valueFactoryField = typeof(Lazy)
17 | .GetField("m_valueFactory", BindingFlags.Instance | BindingFlags.NonPublic);
18 |
19 | var valueFactory = (Func)valueFactoryField.GetValue(lazyFactory);
20 |
21 | var exportField = valueFactory.Target.GetType()
22 | .GetField("export", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
23 |
24 | var export = exportField.GetValue(valueFactory.Target) as Export;
25 | var memberInfo = (LazyMemberInfo)export.Definition.GetType()
26 | .GetProperty("ExportingLazyMember").GetValue(export.Definition, null);
27 |
28 | return memberInfo.GetAccessors()[0] as Type;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/NRack.Server/NRack.Server.Net45.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {7800B7EA-FB3A-4305-9EE7-74A7B5744C45}
8 | Exe
9 | Properties
10 | NRack.Server
11 | NRack.Server
12 | v4.5
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\net45\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 | false
25 |
26 |
27 | pdbonly
28 | true
29 | bin\net45\Release\
30 | TRACE
31 | prompt
32 | 4
33 | false
34 |
35 |
36 |
37 |
38 |
39 |
40 | ..\packages\AnyLog.0.1.8\lib\net45\AnyLog.dll
41 | True
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | GlobalAssemblyInfo.cs
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | Code
84 |
85 |
86 |
87 |
88 | Component
89 |
90 |
91 | NRackService.cs
92 |
93 |
94 | Component
95 |
96 |
97 | NRackServiceInstaller.cs
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | {406671C6-5DCB-4B23-BD28-FB02C235EAE4}
107 | NRack.Base.Net45
108 |
109 |
110 |
111 |
112 |
113 | PreserveNewest
114 |
115 |
116 | PreserveNewest
117 |
118 |
119 | PreserveNewest
120 |
121 |
122 | PreserveNewest
123 |
124 |
125 |
126 |
127 |
128 |
135 |
--------------------------------------------------------------------------------
/src/NRack.Server/NRack.Server.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {7800B7EA-FB3A-4305-9EE7-74A7B5744C45}
8 | Exe
9 | Properties
10 | NRack.Server
11 | NRack.Server
12 | v4.0
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\net40\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\net40\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 |
36 |
37 |
38 | ..\packages\AnyLog.0.1.8\lib\net40\AnyLog.dll
39 | True
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | GlobalAssemblyInfo.cs
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | Code
85 |
86 |
87 |
88 |
89 | Component
90 |
91 |
92 | NRackService.cs
93 |
94 |
95 | Component
96 |
97 |
98 | NRackServiceInstaller.cs
99 |
100 |
101 |
102 |
103 |
104 | {406671C6-5DCB-4B23-BD28-FB02C235EAE4}
105 | NRack.Base
106 |
107 |
108 |
109 |
110 |
111 | PreserveNewest
112 |
113 |
114 | PreserveNewest
115 |
116 |
117 | PreserveNewest
118 |
119 |
120 | PreserveNewest
121 |
122 |
123 |
124 |
125 |
126 |
133 |
--------------------------------------------------------------------------------
/src/NRack.Server/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("NRack.Server")]
9 | [assembly: AssemblyDescription("NRack.Server")]
10 | [assembly: AssemblyConfiguration("")]
11 | // Setting ComVisible to false makes the types in this assembly not visible
12 | // to COM components. If you need to access a type in this assembly from
13 | // COM, set the ComVisible attribute to true on that type.
14 | [assembly: ComVisible(false)]
15 |
16 | // The following GUID is for the ID of the typelib if this project is exposed to COM
17 | [assembly: Guid("89c20989-7759-40db-abbb-217e7229808c")]
18 |
--------------------------------------------------------------------------------
/src/NRack.Server/Recycle/AssemblyUpdatedRecycleTrigger.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Specialized;
4 | using System.ComponentModel.Composition;
5 | using System.IO;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using NRack.Base;
10 | using NRack.Base.Configuration;
11 | using NRack.Base.Provider;
12 | using NRack.Server.Isolation;
13 |
14 | namespace NRack.Server.Recycle
15 | {
16 | [Export(typeof(IRecycleTrigger))]
17 | [ProviderMetadata(TriggerName)]
18 | public class AssemblyUpdatedRecycleTrigger : IRecycleTrigger
19 | {
20 | private int m_CheckInterval;
21 | private int m_RestartRelay;
22 |
23 | internal const string TriggerName = "AssemblyUpdatedTrigger";
24 |
25 | public string Name
26 | {
27 | get
28 | {
29 | return TriggerName;
30 | }
31 | }
32 |
33 | public bool Initialize(NameValueCollection options)
34 | {
35 | var checkInterval = 0;
36 |
37 | if (!int.TryParse(options.GetValue("checkInterval", "5"), out checkInterval))
38 | return false;
39 |
40 | m_CheckInterval = checkInterval;
41 |
42 | var restartDelay = 0;
43 |
44 | if (!int.TryParse(options.GetValue("restartDelay", "1"), out restartDelay))
45 | return false;
46 |
47 | m_RestartRelay = restartDelay;
48 |
49 | return true;
50 | }
51 |
52 | private bool IsDeplayOverdue(DateTime lastUpdatedTime)
53 | {
54 | if (lastUpdatedTime.AddMinutes(m_RestartRelay) <= DateTime.Now)
55 | return true;
56 |
57 | return false;
58 | }
59 |
60 | public bool NeedBeRecycled(IManagedApp app, StatusInfoCollection status)
61 | {
62 | var state = (app as IsolationApp).AssemblyUpdateState;
63 |
64 | // not in running state
65 | if (state == null)
66 | return false;
67 |
68 | if (state.LastUpdatedTime > state.CurrentAssemblyTime)
69 | {
70 | // check to see if there is any latest update
71 | // if yes, deplay much longer time
72 | state.TryCheckUpdate();
73 | return IsDeplayOverdue(state.LastUpdatedTime);
74 | }
75 |
76 | // next check time has not reached yet
77 | if (state.LastCheckTime.AddMinutes(m_CheckInterval) > DateTime.Now)
78 | return false;
79 |
80 | if (!state.TryCheckUpdate())
81 | return false;
82 |
83 | return IsDeplayOverdue(state.LastUpdatedTime);
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/NRack.Server/Recycle/IRecycleTrigger.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Specialized;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using NRack.Base;
8 |
9 | namespace NRack.Server.Recycle
10 | {
11 | public interface IRecycleTrigger
12 | {
13 | string Name { get; }
14 |
15 | bool Initialize(NameValueCollection options);
16 |
17 | bool NeedBeRecycled(IManagedApp app, StatusInfoCollection status);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/NRack.Server/Recycle/MemoryRecycleTrigger.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Specialized;
4 | using System.ComponentModel.Composition;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using NRack.Base;
9 | using NRack.Base.Configuration;
10 | using NRack.Base.Metadata;
11 | using NRack.Base.Provider;
12 |
13 | namespace NRack.Server.Recycle
14 | {
15 | [Export(typeof(IRecycleTrigger))]
16 | [ProviderMetadata(TriggerName)]
17 | public class MemoryRecycleTrigger : IRecycleTrigger
18 | {
19 | private long m_MaxMemoryUsage;
20 |
21 | internal const string TriggerName = "MemoryTrigger";
22 |
23 | public string Name
24 | {
25 | get
26 | {
27 | return TriggerName;
28 | }
29 | }
30 |
31 | public bool Initialize(NameValueCollection options)
32 | {
33 | if (long.TryParse(options.GetValue("maxMemoryUsage"), out m_MaxMemoryUsage) || m_MaxMemoryUsage <= 0)
34 | return false;
35 |
36 | return true;
37 | }
38 |
39 | public bool NeedBeRecycled(IManagedApp app, StatusInfoCollection status)
40 | {
41 | var memoryUsage = status[StatusInfoKeys.MemoryUsage];
42 |
43 | if (memoryUsage == null)
44 | return false;
45 |
46 | return (long)memoryUsage >= m_MaxMemoryUsage;
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/NRack.Server/Recycle/RecycleTriggerConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using NRack.Base.Config;
8 |
9 | namespace NRack.Server.Config
10 | {
11 | public class RecycleTriggerConfig : ConfigurationElementBase
12 | {
13 | public RecycleTriggerConfig()
14 | : base(true)
15 | {
16 |
17 | }
18 |
19 | [ConfigurationProperty("type", IsRequired = false)]
20 | public string Type
21 | {
22 | get { return this["type"] as string; }
23 | }
24 | }
25 |
26 | [ConfigurationCollection(typeof(RecycleTriggerConfig), AddItemName = "trigger")]
27 | class RecycleTriggerConfigCollection : GenericConfigurationElementCollectionBase
28 | {
29 |
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/NRack.Server/RemoteAppGroup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using NRack.Base;
6 | using NRack.Base.Config;
7 | using NRack.Base.Metadata;
8 |
9 | namespace NRack.Server
10 | {
11 | class ManagedAppGroup : IManagedApp
12 | {
13 | public string Name { get; private set; }
14 |
15 | public IManagedApp[] Items { get; private set; }
16 |
17 | public ManagedAppGroup(string name, IEnumerable groupItems)
18 | {
19 | if (string.IsNullOrEmpty(name))
20 | throw new ArgumentNullException("name");
21 |
22 | if (groupItems == null || !groupItems.Any())
23 | throw new ArgumentNullException("name");
24 |
25 | Name = name;
26 | Items = groupItems.ToArray();
27 | }
28 |
29 | public bool Setup(IBootstrap bootstrap, IServerConfig config)
30 | {
31 | Config = config;
32 |
33 | foreach (var item in Items)
34 | {
35 | if (!item.Setup(bootstrap, config))
36 | return false;
37 | }
38 |
39 | return true;
40 | }
41 |
42 | public bool Start()
43 | {
44 | foreach (var item in Items)
45 | {
46 | if (!item.Start())
47 | return false;
48 | }
49 |
50 | return true;
51 | }
52 |
53 | public void Stop()
54 | {
55 | foreach (var item in Items)
56 | {
57 | item.Stop();
58 | }
59 | }
60 |
61 |
62 | public IServerConfig Config { get; private set; }
63 |
64 | public AppServerMetadata GetMetadata()
65 | {
66 | throw new NotImplementedException();
67 | }
68 |
69 |
70 | public ServerState State { get; private set; }
71 |
72 |
73 | public bool CanBeRecycled()
74 | {
75 | return true;
76 | }
77 |
78 | public StatusInfoCollection CollectStatus()
79 | {
80 | throw new NotImplementedException();
81 | }
82 |
83 | public void ReportPotentialConfigChange(IServerConfig config)
84 | {
85 | foreach (var item in Items)
86 | {
87 | item.ReportPotentialConfigChange(config);
88 | }
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/NRack.Server/RemoteAppTypeValidator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.Composition.Hosting;
4 | using System.Linq;
5 | using System.Reflection;
6 | using System.Text;
7 | using NRack.Base;
8 | using NRack.Base.Metadata;
9 |
10 | namespace NRack.Server
11 | {
12 | [Serializable]
13 | public class RemoteTypeLoadResult
14 | {
15 | public bool Result { get; set; }
16 |
17 | public T Value { get; set; }
18 |
19 | public string Message { get; set; }
20 | }
21 |
22 | public class RemoteAppTypeValidator : MarshalByRefObject
23 | {
24 | private CompositionContainer m_ExportProvider;
25 |
26 | public RemoteAppTypeValidator()
27 | {
28 | m_ExportProvider = AppDomain.CurrentDomain.GetCurrentAppDomainExportProvider();
29 | }
30 |
31 | public RemoteTypeLoadResult GetServerMetadata(string serverTypeName)
32 | {
33 | Lazy lazyServerFactory = null;
34 |
35 | try
36 | {
37 | lazyServerFactory = m_ExportProvider.GetExports()
38 | .FirstOrDefault(f => f.Metadata.Name.Equals(serverTypeName, StringComparison.OrdinalIgnoreCase));
39 | }
40 | catch (ReflectionTypeLoadException e)
41 | {
42 | var msg = e.Message;
43 |
44 | foreach (var le in e.LoaderExceptions)
45 | {
46 | msg += Environment.NewLine + le.Message;
47 | }
48 |
49 | return new RemoteTypeLoadResult { Message = msg };
50 | }
51 |
52 | AppServerMetadata metadata = null;
53 |
54 | try
55 | {
56 | if (lazyServerFactory != null)
57 | {
58 | metadata = new AppServerMetadata(lazyServerFactory.Metadata, lazyServerFactory.GetExportType());
59 | }
60 | else
61 | {
62 | metadata = AppServerMetadata.GetAppServerMetadata(Type.GetType(serverTypeName, true, true));
63 | }
64 | }
65 | catch(Exception e)
66 | {
67 | return new RemoteTypeLoadResult { Message = e.Message + Environment.NewLine + e.StackTrace };
68 | }
69 |
70 | return new RemoteTypeLoadResult { Result = true, Value = metadata };
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/NRack.Server/RemoteBootstrapProxy.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using AnyLog;
6 | using NRack.Base;
7 | using NRack.Base.Config;
8 |
9 | namespace NRack.Server
10 | {
11 | class RemoteBootstrapProxy : MarshalByRefObject, IBootstrap, ILoggerProvider
12 | {
13 | class ServerProxy : MarshalByRefObject, IManagedApp
14 | {
15 | private IManagedApp m_ManagedApp;
16 |
17 | public ServerProxy(IManagedApp app)
18 | {
19 | m_ManagedApp = app;
20 | }
21 |
22 | public ServerState State
23 | {
24 | get { return m_ManagedApp.State; }
25 | }
26 |
27 | public string Name
28 | {
29 | get { return m_ManagedApp.Name; }
30 | }
31 | public bool Start()
32 | {
33 | return m_ManagedApp.Start();
34 | }
35 |
36 | public void Stop()
37 | {
38 | m_ManagedApp.Stop();
39 | }
40 |
41 | public bool Setup(IBootstrap bootstrap, IServerConfig config)
42 | {
43 | throw new NotImplementedException();
44 | }
45 |
46 | public IServerConfig Config
47 | {
48 | get { return m_ManagedApp.Config; }
49 | }
50 |
51 | public AppServerMetadata GetMetadata()
52 | {
53 | return m_ManagedApp.GetMetadata();
54 | }
55 |
56 | public bool CanBeRecycled()
57 | {
58 | return m_ManagedApp.CanBeRecycled();
59 | }
60 |
61 | public StatusInfoCollection CollectStatus()
62 | {
63 | return m_ManagedApp.CollectStatus();
64 | }
65 |
66 | public void ReportPotentialConfigChange(IServerConfig config)
67 | {
68 | m_ManagedApp.ReportPotentialConfigChange(config);
69 | }
70 |
71 | public override object InitializeLifetimeService()
72 | {
73 | //Never expire
74 | return null;
75 | }
76 | }
77 |
78 | private IBootstrap m_Bootstrap;
79 |
80 | private List m_ManagedApps;
81 |
82 | public RemoteBootstrapProxy(IBootstrap innerBootstrap)
83 | {
84 | m_Bootstrap = innerBootstrap;
85 | m_ManagedApps = new List();
86 |
87 | foreach (var s in m_Bootstrap.AppServers)
88 | {
89 | if (s is MarshalByRefObject)
90 | m_ManagedApps.Add(s);
91 | else
92 | m_ManagedApps.Add(new ServerProxy(s));
93 | }
94 | }
95 |
96 | public RemoteBootstrapProxy()
97 | : this(AppDomain.CurrentDomain.GetBootstrap())
98 | {
99 |
100 | }
101 |
102 | public IEnumerable AppServers
103 | {
104 | get
105 | {
106 | return m_ManagedApps;
107 | }
108 | }
109 |
110 | ILog ILoggerProvider.Logger
111 | {
112 | get
113 | {
114 | var loggerProvider = m_Bootstrap as ILoggerProvider;
115 |
116 | if (loggerProvider == null)
117 | return null;
118 |
119 | return loggerProvider.Logger;
120 | }
121 | }
122 |
123 | public string ConfigFilePath
124 | {
125 | get
126 | {
127 | return m_Bootstrap.ConfigFilePath;
128 | }
129 | }
130 |
131 | public bool Initialize()
132 | {
133 | throw new NotSupportedException();
134 | }
135 |
136 | public void Start()
137 | {
138 | throw new NotSupportedException();
139 | }
140 |
141 | public void Stop()
142 | {
143 | throw new NotSupportedException();
144 | }
145 |
146 | public override object InitializeLifetimeService()
147 | {
148 | //Never expire
149 | return null;
150 | }
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/src/NRack.Server/Service/NRackService.Designer.cs:
--------------------------------------------------------------------------------
1 | using System.Configuration;
2 |
3 | namespace NRack.Server.Service
4 | {
5 | partial class NRackService
6 | {
7 | ///
8 | /// Required designer variable.
9 | ///
10 | private System.ComponentModel.IContainer components = null;
11 |
12 | ///
13 | /// Clean up any resources being used.
14 | ///
15 | /// true if managed resources should be disposed; otherwise, false.
16 | protected override void Dispose(bool disposing)
17 | {
18 | if (disposing && (components != null))
19 | {
20 | components.Dispose();
21 | }
22 | base.Dispose(disposing);
23 | }
24 |
25 | #region Component Designer generated code
26 |
27 | ///
28 | /// Required method for Designer support - do not modify
29 | /// the contents of this method with the code editor.
30 | ///
31 | private void InitializeComponent()
32 | {
33 | components = new System.ComponentModel.Container();
34 | }
35 |
36 | #endregion
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/NRack.Server/Service/NRackService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Configuration;
5 | using System.Diagnostics;
6 | using System.ServiceProcess;
7 | using System.Text;
8 | using NRack.Base;
9 |
10 | namespace NRack.Server.Service
11 | {
12 | partial class NRackService : ServiceBase
13 | {
14 | private IBootstrap m_Bootstrap;
15 |
16 | public NRackService()
17 | {
18 | InitializeComponent();
19 | ServiceName = ConfigurationManager.AppSettings["ServiceName"];
20 | m_Bootstrap = BootstrapFactory.CreateBootstrap();
21 | }
22 |
23 | protected override void OnStart(string[] args)
24 | {
25 | if (!m_Bootstrap.Initialize())
26 | return;
27 |
28 | m_Bootstrap.Start();
29 | }
30 |
31 | protected override void OnStop()
32 | {
33 | m_Bootstrap.Stop();
34 | base.OnStop();
35 | }
36 |
37 | protected override void OnShutdown()
38 | {
39 | m_Bootstrap.Stop();
40 | base.OnShutdown();
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/NRack.Server/Service/NRackServiceInstaller.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace NRack.Server.Service
2 | {
3 | partial class NRackServiceInstaller
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Component Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | components = new System.ComponentModel.Container();
32 | }
33 |
34 | #endregion
35 | }
36 | }
--------------------------------------------------------------------------------
/src/NRack.Server/Service/NRackServiceInstaller.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Configuration;
5 | using System.Configuration.Install;
6 | using System.ServiceProcess;
7 |
8 | namespace NRack.Server.Service
9 | {
10 | [RunInstaller(true)]
11 | public partial class NRackServiceInstaller : Installer
12 | {
13 | private ServiceInstaller serviceInstaller;
14 | private ServiceProcessInstaller processInstaller;
15 |
16 | public NRackServiceInstaller()
17 | {
18 | InitializeComponent();
19 |
20 | processInstaller = new ServiceProcessInstaller();
21 | serviceInstaller = new ServiceInstaller();
22 |
23 | processInstaller.Account = ServiceAccount.LocalSystem;
24 | serviceInstaller.StartType = ServiceStartMode.Automatic;
25 | serviceInstaller.ServiceName = ConfigurationManager.AppSettings["ServiceName"];
26 |
27 | var serviceDescription = ConfigurationManager.AppSettings["ServiceDescription"];
28 | if (!string.IsNullOrEmpty(serviceDescription))
29 | serviceInstaller.Description = serviceDescription;
30 |
31 | var servicesDependedOn = new List { "tcpip" };
32 | var servicesDependedOnConfig = ConfigurationManager.AppSettings["ServicesDependedOn"];
33 |
34 | if (!string.IsNullOrEmpty(servicesDependedOnConfig))
35 | servicesDependedOn.AddRange(servicesDependedOnConfig.Split(new char[] { ',', ';' }));
36 |
37 | serviceInstaller.ServicesDependedOn = servicesDependedOn.ToArray();
38 |
39 | Installers.Add(serviceInstaller);
40 | Installers.Add(processInstaller);
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/src/NRack.Server/Service/SelfInstaller.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Configuration.Install;
3 | using System.Reflection;
4 |
5 | namespace NRack.Server.Service
6 | {
7 | public static class SelfInstaller
8 | {
9 | private static readonly string _exePath = Assembly.GetEntryAssembly().Location;
10 |
11 | public static bool InstallMe()
12 | {
13 | try
14 | {
15 | ManagedInstallerClass.InstallHelper(new string[] { _exePath });
16 | }
17 | catch
18 | {
19 | return false;
20 | }
21 | return true;
22 | }
23 |
24 | public static bool UninstallMe()
25 | {
26 | try
27 | {
28 | ManagedInstallerClass.InstallHelper(new string[] { "/u", _exePath });
29 | }
30 | catch
31 | {
32 | return false;
33 | }
34 |
35 | return true;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/NRack.Server/Utils/PerformanceCounterInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using NRack.Base.Metadata;
7 |
8 | namespace NRack.Server.Utils
9 | {
10 | public class PerformanceCounterInfo
11 | {
12 | ///
13 | /// Gets or sets the performance counter category.
14 | ///
15 | ///
16 | /// The category.
17 | ///
18 | public string Category { get; set; }
19 |
20 | ///
21 | /// Gets or sets the performance counter name.
22 | ///
23 | ///
24 | /// The name.
25 | ///
26 | public string Name { get; set; }
27 |
28 |
29 | ///
30 | /// Gets or sets the status information key.
31 | ///
32 | ///
33 | /// The status information key.
34 | ///
35 | public string StatusInfoKey { get; set; }
36 |
37 | ///
38 | /// Gets or sets the performacne counter data reader.
39 | ///
40 | ///
41 | /// The reader.
42 | ///
43 | public Func Read { get; set; }
44 |
45 |
46 | internal static PerformanceCounterInfo[] GetDefaultPerformanceCounterDefinitions()
47 | {
48 | return new PerformanceCounterInfo[]
49 | {
50 | new PerformanceCounterInfo
51 | {
52 | Category = "Process",
53 | Name = "% Processor Time",
54 | StatusInfoKey = StatusInfoKeys.CpuUsage,
55 | Read = (value) => value / Environment.ProcessorCount
56 | },
57 | new PerformanceCounterInfo
58 | {
59 | Category = "Process",
60 | Name = "Thread Count",
61 | StatusInfoKey = StatusInfoKeys.TotalThreadCount,
62 | Read = (value) => (int)value
63 | },
64 | new PerformanceCounterInfo
65 | {
66 | Category = "Process",
67 | Name = "Working Set",
68 | StatusInfoKey = StatusInfoKeys.MemoryUsage,
69 | Read = (value) => (long)value
70 | }
71 | };
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/NRack.Server/nrack.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 | NRack.Server.exe -c %1 %2
3 |
--------------------------------------------------------------------------------
/src/NRack.Server/nrack.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | mono NRack.Server.exe -c $1 $2
3 |
--------------------------------------------------------------------------------
/src/NRack.Server/packages.NRack.Server.Net45.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/NRack.Server/packages.NRack.Server.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/NRack.Test/AppDomainIsolationTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using NUnit.Framework;
7 |
8 | namespace NRack.Test
9 | {
10 | [TestFixture]
11 | public class AppDomainIsolationTest : Test
12 | {
13 | protected override string ConfigFile
14 | {
15 | get
16 | {
17 | return "AppDomainIsolation.config";
18 | }
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/NRack.Test/Asserts/Config/AppDomainIsolation.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/NRack.Test/Asserts/Config/Basic.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/NRack.Test/Asserts/Config/ProcessIsolation.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/NRack.Test/NRack.Test.Net45.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | {B145DFCA-3A62-4FC6-A3F1-EA970719DC9F}
7 | Library
8 | NRack.Test
9 | NRack.Test
10 | v4.5
11 |
12 |
13 | true
14 | full
15 | false
16 | bin\Debug
17 | DEBUG;
18 | prompt
19 | 4
20 | false
21 |
22 |
23 | full
24 | true
25 | bin\Release
26 | prompt
27 | 4
28 | false
29 |
30 |
31 |
32 | ..\packages\AnyLog.0.1.8\lib\net45\AnyLog.dll
33 | True
34 |
35 |
36 |
37 | ..\packages\NUnit.2.6.3\lib\nunit.framework.dll
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | PreserveNewest
52 |
53 |
54 | PreserveNewest
55 |
56 |
57 |
58 | PreserveNewest
59 |
60 |
61 |
62 |
63 | {406671C6-5DCB-4B23-BD28-FB02C235EAE4}
64 | NDock.Base.Net45
65 |
66 |
67 | {7800B7EA-FB3A-4305-9EE7-74A7B5744C45}
68 | NDock.Server.Net45
69 |
70 |
71 | {93a2e31d-9af3-4c9e-986c-1659309f5436}
72 | NDock.Worker.Net45
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/src/NRack.Test/NRack.Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | {B145DFCA-3A62-4FC6-A3F1-EA970719DC9F}
7 | Library
8 | NRack.Test
9 | NRack.Test
10 | v4.5
11 |
12 |
13 | true
14 | full
15 | false
16 | bin\Debug
17 | DEBUG;
18 | prompt
19 | 4
20 | false
21 |
22 |
23 | full
24 | true
25 | bin\Release
26 | prompt
27 | 4
28 | false
29 |
30 |
31 |
32 | ..\packages\AnyLog.0.1.8\lib\net45\AnyLog.dll
33 | True
34 |
35 |
36 |
37 | ..\packages\NUnit.2.6.3\lib\nunit.framework.dll
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | PreserveNewest
52 |
53 |
54 | PreserveNewest
55 |
56 |
57 |
58 | PreserveNewest
59 |
60 |
61 |
62 |
63 | {406671C6-5DCB-4B23-BD28-FB02C235EAE4}
64 | NRack.Base
65 |
66 |
67 | {7800B7EA-FB3A-4305-9EE7-74A7B5744C45}
68 | NRack.Server
69 |
70 |
71 | {93a2e31d-9af3-4c9e-986c-1659309f5436}
72 | NRack.Worker
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/src/NRack.Test/ProcessIsolationTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using NUnit.Framework;
8 |
9 | namespace NRack.Test
10 | {
11 | [TestFixture]
12 | public class ProcessIsolationTest : Test
13 | {
14 | protected override string ConfigFile
15 | {
16 | get
17 | {
18 | return "ProcessIsolation.config";
19 | }
20 | }
21 |
22 | [Test]
23 | public void ConfigurationShareTest()
24 | {
25 | StartStopWrap(() =>
26 | {
27 | var NRackTextFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "NRack.Test.txt");
28 |
29 | if (!File.Exists(NRackTextFilePath))
30 | Assert.Fail(string.Format("The file {0} was not generated.", NRackTextFilePath));
31 |
32 | Assert.AreEqual("Hello NRack", File.ReadAllText(NRackTextFilePath, Encoding.UTF8));
33 |
34 | File.Delete(NRackTextFilePath);
35 | });
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/NRack.Test/Test.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 | using NRack.Base;
9 | using NRack.Server;
10 | using NUnit.Framework;
11 |
12 | namespace NRack.Test
13 | {
14 | [TestFixture]
15 | public class Test
16 | {
17 | protected virtual string ConfigFile
18 | {
19 | get { return "Basic.config"; }
20 | }
21 |
22 | private IBootstrap GetBootstrap()
23 | {
24 | var configFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Asserts", "Config", ConfigFile);
25 | return BootstrapFactory.CreateBootstrapFromConfigFile(configFile);
26 | }
27 |
28 | [Test]
29 | public void ConfigLoadTest()
30 | {
31 | var bootstrap = GetBootstrap();
32 | Assert.IsNotNull(bootstrap);
33 | Assert.IsTrue(bootstrap.Initialize());
34 | }
35 |
36 | [Test]
37 | public void StartStopTest()
38 | {
39 | StartStopWrap(null);
40 | }
41 |
42 | protected void StartStopWrap(Action action)
43 | {
44 | var bootstrap = GetBootstrap();
45 | Assert.IsNotNull(bootstrap);
46 | Assert.IsTrue(bootstrap.Initialize());
47 |
48 | var server = bootstrap.AppServers.FirstOrDefault();
49 |
50 | Assert.AreEqual(ServerState.NotStarted, server.State);
51 |
52 | bootstrap.Start();
53 | Assert.AreEqual(ServerState.Running, server.State);
54 |
55 | if(action != null)
56 | action();
57 |
58 | bootstrap.Stop();
59 | Assert.AreEqual(ServerState.NotStarted, server.State);
60 | }
61 |
62 | [Test]
63 | public void StatusCollectTest()
64 | {
65 | StartStopWrap(() =>
66 | {
67 | //Thread.Sleep(1000 * 60 * 5);
68 | });
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/NRack.Test/TestAppServer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using NRack.Base;
3 | using NRack.Base.Config;
4 | using NRack.Base.Metadata;
5 | using System.ComponentModel.Composition.Hosting;
6 | using System.Configuration;
7 | using System.IO;
8 | using System.Text;
9 |
10 | namespace NRack.Test
11 | {
12 | [AppServerMetadata("TestAppServer")]
13 | public class TestAppServer : AppServer
14 | {
15 | public override bool Start()
16 | {
17 | var NRackText = ConfigurationManager.AppSettings["NRack.Test"];
18 |
19 | if(!string.IsNullOrEmpty(NRackText))
20 | {
21 | var NRackTextFilePath = Path.Combine(Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).Parent.FullName, "NRack.Test.txt");
22 | File.WriteAllText(NRackTextFilePath, NRackText, Encoding.UTF8);
23 | }
24 |
25 | return true;
26 | }
27 |
28 | public override void Stop()
29 | {
30 |
31 | }
32 | }
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/src/NRack.Test/packages.NRack.Test.Net45.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/NRack.Test/packages.NRack.Test.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/NRack.Worker/ManagedAppWorker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using System.Text;
6 | using AnyLog;
7 | using NRack.Base;
8 | using NRack.Base.Config;
9 | using NRack.Base.Configuration;
10 | using NRack.Base.Metadata;
11 | using NRack.Server;
12 | using NRack.Server.Isolation;
13 |
14 | namespace NRack.Worker
15 | {
16 | ///
17 | /// The service exposed to bootstrap to control the agent
18 | ///
19 | public class ManagedAppWorker : MarshalByRefObject, IRemoteManagedApp
20 | {
21 | private IManagedApp m_AppServer;
22 |
23 | #pragma warning disable 0414
24 | private AssemblyImport m_AssemblyImporter;
25 | #pragma warning restore 0414
26 |
27 | private ILog m_Log;
28 |
29 | ///
30 | /// Initializes a new instance of the class.
31 | ///
32 | public ManagedAppWorker()
33 | {
34 |
35 | }
36 |
37 | public bool Setup(string serverType, string bootstrapUri, string assemblyImportRoot, IServerConfig config, string startupConfigFile)
38 | {
39 | m_AssemblyImporter = new AssemblyImport(assemblyImportRoot);
40 |
41 | if(!string.IsNullOrEmpty(startupConfigFile))
42 | {
43 | AppDomain.CurrentDomain.ResetConfiguration(startupConfigFile);
44 | }
45 |
46 | var serviceType = Type.GetType(serverType);
47 | m_AppServer = (IManagedApp)Activator.CreateInstance(serviceType);
48 |
49 | var bootstrap = (IBootstrap)Activator.GetObject(typeof(IBootstrap), bootstrapUri);
50 |
51 | var ret = m_AppServer.Setup(bootstrap, config);
52 |
53 | if (ret)
54 | {
55 | m_Log = ((IAppServer)m_AppServer).Logger;
56 | AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
57 | }
58 |
59 | return ret;
60 | }
61 |
62 | void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
63 | {
64 | if (m_Log != null)
65 | {
66 | m_Log.Error("The process crashed for an unhandled exception!", (Exception)e.ExceptionObject);
67 | }
68 | }
69 |
70 | ///
71 | /// Starts this instance.
72 | ///
73 | ///
74 | public bool Start()
75 | {
76 | return m_AppServer.Start();
77 | }
78 |
79 | ///
80 | /// Stops this instance.
81 | ///
82 | public void Stop()
83 | {
84 | m_AppServer.Stop();
85 | }
86 |
87 | AppServerMetadata IManagedAppBase.GetMetadata()
88 | {
89 | return m_AppServer.GetMetadata();
90 | }
91 |
92 | ///
93 | /// Gets the name.
94 | ///
95 | public string Name
96 | {
97 | get { return m_AppServer.Name; }
98 | }
99 |
100 | ///
101 | /// Obtains a lifetime service object to control the lifetime policy for this instance.
102 | /// Return null, never expire
103 | ///
104 | ///
105 | /// An object of type used to control the lifetime policy for this instance. This is the current lifetime service object for this instance if one exists; otherwise, a new lifetime service object initialized to the value of the property.
106 | ///
107 | ///
108 | ///
109 | ///
110 | public override object InitializeLifetimeService()
111 | {
112 | return null;
113 | }
114 |
115 | public bool CanBeRecycled()
116 | {
117 | return m_AppServer.CanBeRecycled();
118 | }
119 |
120 |
121 | public StatusInfoCollection CollectStatus()
122 | {
123 | return m_AppServer.CollectStatus();
124 | }
125 |
126 | public void ReportPotentialConfigChange(IServerConfig config)
127 | {
128 | m_AppServer.ReportPotentialConfigChange(config);
129 | }
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/NRack.Worker/NRack.Worker.Net45.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {93A2E31D-9AF3-4C9E-986C-1659309F5436}
8 | Exe
9 | Properties
10 | NRack.Worker
11 | NRack.Worker
12 | v4.5
13 | 512
14 |
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\net45\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 | false
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | bin\net45\Release\
32 | TRACE
33 | prompt
34 | 4
35 | false
36 |
37 |
38 |
39 | ..\packages\AnyLog.0.1.8\lib\net45\AnyLog.dll
40 | True
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | GlobalAssemblyInfo.cs
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | {406671C6-5DCB-4B23-BD28-FB02C235EAE4}
61 | NRack.Base.Net45
62 |
63 |
64 | {7800B7EA-FB3A-4305-9EE7-74A7B5744C45}
65 | NRack.Server.Net45
66 |
67 |
68 |
69 |
70 |
71 |
72 |
79 |
--------------------------------------------------------------------------------
/src/NRack.Worker/NRack.Worker.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {93A2E31D-9AF3-4C9E-986C-1659309F5436}
8 | Exe
9 | Properties
10 | NRack.Worker
11 | NRack.Worker
12 | v4.0
13 | 512
14 |
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\net40\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\net40\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 | ..\packages\AnyLog.0.1.8\lib\net40\AnyLog.dll
38 | True
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | GlobalAssemblyInfo.cs
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | {406671C6-5DCB-4B23-BD28-FB02C235EAE4}
59 | NRack.Base
60 |
61 |
62 | {7800B7EA-FB3A-4305-9EE7-74A7B5744C45}
63 | NRack.Server
64 |
65 |
66 |
67 |
68 |
69 |
70 |
77 |
--------------------------------------------------------------------------------
/src/NRack.Worker/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Reflection;
7 | using System.Runtime.Remoting;
8 | using System.Runtime.Remoting.Channels;
9 | using System.Runtime.Remoting.Channels.Ipc;
10 | using System.Runtime.Serialization.Formatters;
11 | using System.Text;
12 | using System.Threading.Tasks;
13 | using NRack.Base;
14 | using NRack.Server;
15 | using NRack.Server.Isolation;
16 | using NRack.Server.Isolation.ProcessIsolation;
17 |
18 | namespace NRack.Worker
19 | {
20 | class Program
21 | {
22 | static void Main(string[] args)
23 | {
24 | if (args == null)
25 | throw new ArgumentNullException("args");
26 |
27 | if (args.Length != 1)
28 | throw new ArgumentException("Arguments number doesn't match!", "args");
29 |
30 | var name = args[0];
31 |
32 | if (string.IsNullOrEmpty(name))
33 | throw new Exception("Name cannot be null or empty.");
34 |
35 | name = name.Trim('"');
36 |
37 | var channelPort = string.Format(ProcessAppConst.PortNameTemplate, name, Process.GetCurrentProcess().Id);
38 |
39 | var currentDomain = AppDomain.CurrentDomain;
40 |
41 | #pragma warning disable 0618 // Type or member is obsolete
42 | currentDomain.SetCachePath(Path.Combine(Path.Combine(currentDomain.BaseDirectory, IsolationAppConst.ShadowCopyDir), name));
43 | currentDomain.SetShadowCopyFiles();
44 | #pragma warning restore 0618 // Type or member is obsolete
45 |
46 | var root = Path.Combine(Path.Combine(currentDomain.BaseDirectory, ProcessAppConst.WorkingDir), name);
47 |
48 | //Hack to change the default AppDomain's root
49 | if (NRackEnv.IsMono) //for Mono
50 | {
51 | var pro = typeof(AppDomain).GetProperty("SetupInformationNoCopy", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty);
52 | var setupInfo = (AppDomainSetup)pro.GetValue(currentDomain, null);
53 | setupInfo.ApplicationBase = root;
54 | }
55 | else // for .NET
56 | {
57 | currentDomain.SetData("APPBASE", root);
58 | }
59 |
60 | currentDomain.SetData(typeof(IsolationMode).Name, IsolationMode.Process);
61 |
62 | try
63 | {
64 | var serverChannel = new IpcServerChannel("IpcAgent", channelPort, new BinaryServerFormatterSinkProvider { TypeFilterLevel = TypeFilterLevel.Full });
65 | var clientChannel = new IpcClientChannel();
66 | ChannelServices.RegisterChannel(serverChannel, false);
67 | ChannelServices.RegisterChannel(clientChannel, false);
68 | RemotingConfiguration.RegisterWellKnownServiceType(typeof(ManagedAppWorker), ProcessAppConst.WorkerRemoteName, WellKnownObjectMode.Singleton);
69 |
70 | Console.WriteLine("Ok");
71 |
72 | var line = Console.ReadLine();
73 |
74 | while (!"quit".Equals(line, StringComparison.OrdinalIgnoreCase))
75 | {
76 | line = Console.ReadLine();
77 | }
78 | }
79 | catch
80 | {
81 | Console.Write("Failed");
82 | }
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/NRack.Worker/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("NRack.Worker")]
9 | [assembly: AssemblyDescription("NRack.Worker")]
10 | [assembly: AssemblyConfiguration("")]
11 |
12 | // Setting ComVisible to false makes the types in this assembly not visible
13 | // to COM components. If you need to access a type in this assembly from
14 | // COM, set the ComVisible attribute to true on that type.
15 | [assembly: ComVisible(false)]
16 |
17 | // The following GUID is for the ID of the typelib if this project is exposed to COM
18 | [assembly: Guid("7847be9c-f944-4933-ba89-610766a3a0b1")]
--------------------------------------------------------------------------------
/src/NRack.Worker/packages.NRack.Worker.Net45.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/NRack.Worker/packages.NRack.Worker.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/NRack.build:
--------------------------------------------------------------------------------
1 |
2 |
3 | Release
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/NRack.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | NRack
5 | $version$
6 | NRack
7 | Kerry Jiang
8 | Kerry Jiang
9 | http://www.apache.org/licenses/LICENSE-2.0.html
10 | https://github.com/kerryjiang/NRack
11 | false
12 | NRack is a server application container, which can be used for your back end services' hosting and management.
13 |
14 | Copyright 2016
15 | service container host
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/src/NRack.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25123.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRack.Base", "NRack.Base\NRack.Base.csproj", "{406671C6-5DCB-4B23-BD28-FB02C235EAE4}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRack.Server", "NRack.Server\NRack.Server.csproj", "{7800B7EA-FB3A-4305-9EE7-74A7B5744C45}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{6E0C838A-35D5-4D95-B3F0-6D0560F9C2FD}"
11 | ProjectSection(SolutionItems) = preProject
12 | GlobalAssemblyInfo.cs = GlobalAssemblyInfo.cs
13 | EndProjectSection
14 | EndProject
15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRack.Test", "NRack.Test\NRack.Test.csproj", "{B145DFCA-3A62-4FC6-A3F1-EA970719DC9F}"
16 | EndProject
17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRack.Worker", "NRack.Worker\NRack.Worker.csproj", "{93A2E31D-9AF3-4C9E-986C-1659309F5436}"
18 | EndProject
19 | Global
20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
21 | Debug|Any CPU = Debug|Any CPU
22 | Release|Any CPU = Release|Any CPU
23 | EndGlobalSection
24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
25 | {406671C6-5DCB-4B23-BD28-FB02C235EAE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 | {406671C6-5DCB-4B23-BD28-FB02C235EAE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 | {406671C6-5DCB-4B23-BD28-FB02C235EAE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 | {406671C6-5DCB-4B23-BD28-FB02C235EAE4}.Release|Any CPU.Build.0 = Release|Any CPU
29 | {7800B7EA-FB3A-4305-9EE7-74A7B5744C45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30 | {7800B7EA-FB3A-4305-9EE7-74A7B5744C45}.Debug|Any CPU.Build.0 = Debug|Any CPU
31 | {7800B7EA-FB3A-4305-9EE7-74A7B5744C45}.Release|Any CPU.ActiveCfg = Release|Any CPU
32 | {7800B7EA-FB3A-4305-9EE7-74A7B5744C45}.Release|Any CPU.Build.0 = Release|Any CPU
33 | {B145DFCA-3A62-4FC6-A3F1-EA970719DC9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 | {B145DFCA-3A62-4FC6-A3F1-EA970719DC9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
35 | {B145DFCA-3A62-4FC6-A3F1-EA970719DC9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
36 | {93A2E31D-9AF3-4C9E-986C-1659309F5436}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37 | {93A2E31D-9AF3-4C9E-986C-1659309F5436}.Debug|Any CPU.Build.0 = Debug|Any CPU
38 | {93A2E31D-9AF3-4C9E-986C-1659309F5436}.Release|Any CPU.ActiveCfg = Release|Any CPU
39 | {93A2E31D-9AF3-4C9E-986C-1659309F5436}.Release|Any CPU.Build.0 = Release|Any CPU
40 | EndGlobalSection
41 | GlobalSection(SolutionProperties) = preSolution
42 | HideSolutionNode = FALSE
43 | EndGlobalSection
44 | EndGlobal
45 |
--------------------------------------------------------------------------------