├── .gitattributes
├── .github
└── ISSUE_TEMPLATE.md
├── .gitignore
├── .nuget
└── NuGet.exe
├── .paket
├── paket.bootstrapper.exe
└── paket.targets
├── .travis.yml
├── FSharp.CloudAgent.sln
├── GenerateDocs.cmd
├── LICENSE.txt
├── README.md
├── RELEASE_NOTES.md
├── appveyor.yml
├── build.cmd
├── build.fsx
├── build.sh
├── docs
├── content
│ ├── agent-paradigms.fsx
│ ├── azure-service-bus.fsx
│ ├── handling-errors.fsx
│ ├── index.fsx
│ ├── tutorial.fsx
│ └── windows-service-bus.fsx
├── files
│ └── img
│ │ ├── create-a-queue.png
│ │ ├── logo-template.pdn
│ │ ├── logo.png
│ │ └── queues-in-vs.png
└── tools
│ ├── generate.fsx
│ ├── paket.references
│ └── templates
│ └── template.cshtml
├── lib
└── README.md
├── nuget
├── FSharp.CloudAgent.nuspec
├── README.md
└── publish.cmd
├── paket.dependencies
├── paket.lock
├── src
└── FSharp.CloudAgent
│ ├── Actors.fs
│ ├── AssemblyInfo.fs
│ ├── ConnectionFactory.fs
│ ├── CustomAssemblyPermissions.fs
│ ├── FSharp.CloudAgent.fsproj
│ ├── Messaging.fs
│ ├── Types.fs
│ ├── app.config
│ └── paket.references
└── tests
└── FSharp.CloudAgent.Tests
├── Actors.fs
├── AutomaticRetry.fs
├── FSharp.CloudAgent.Tests.fsproj
├── Helpers.fs
├── ProcessBrokeredMessage.fs
├── Script.fsx
├── app.config
└── paket.references
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | # Autodetect text or binary. Do not leave merge conflict markers in the files.
5 | * text=auto merge=union
6 |
7 | # Use LF in the working directory by default. Override with core.autocrlf=true.
8 | *.fs eol=lf
9 | *fsi eol=lf
10 |
11 | # Visual Studio can read LF sln files, but it always writes them as CRLF.
12 | *.sln eol=crlf
13 |
14 | ###############################################################################
15 | # Set default behavior for command prompt diff.
16 | #
17 | # This is need for earlier builds of msysgit that does not have it on by
18 | # default for csharp files.
19 | # Note: This is only used by command line
20 | ###############################################################################
21 | #*.cs diff=csharp
22 |
23 | ###############################################################################
24 | # Set the merge driver for project and solution files
25 | #
26 | # Merging from the command prompt will add diff markers to the files if there
27 | # are conflicts (Merging from VS is not affected by the settings below, in VS
28 | # the diff markers are never inserted). Diff markers may cause the following
29 | # file extensions to fail to load in VS. An alternative would be to treat
30 | # these files as binary and thus will always conflict and require user
31 | # intervention with every merge. To do so, just uncomment the entries below
32 | ###############################################################################
33 | #*.sln merge=binary
34 | #*.csproj merge=binary
35 | #*.vbproj merge=binary
36 | #*.vcxproj merge=binary
37 | #*.vcproj merge=binary
38 | #*.dbproj merge=binary
39 | #*.fsproj merge=binary
40 | #*.lsproj merge=binary
41 | #*.wixproj merge=binary
42 | #*.modelproj merge=binary
43 | #*.sqlproj merge=binary
44 | #*.wwaproj merge=binary
45 |
46 | ###############################################################################
47 | # behavior for image files
48 | #
49 | # image files are treated as binary by default.
50 | ###############################################################################
51 | #*.jpg binary
52 | #*.png binary
53 | #*.gif binary
54 |
55 | ###############################################################################
56 | # diff behavior for common document formats
57 | #
58 | # Convert binary document formats to text before diffing them. This feature
59 | # is only available from the command line. Turn it on by uncommenting the
60 | # entries below.
61 | ###############################################################################
62 | #*.doc diff=astextplain
63 | #*.DOC diff=astextplain
64 | #*.docx diff=astextplain
65 | #*.DOCX diff=astextplain
66 | #*.dot diff=astextplain
67 | #*.DOT diff=astextplain
68 | #*.pdf diff=astextplain
69 | #*.PDF diff=astextplain
70 | #*.rtf diff=astextplain
71 | #*.RTF diff=astextplain
72 |
73 | *.sh text eol=lf
74 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ### Description
2 |
3 | Please provide a succinct description of your issue.
4 |
5 | ### Repro steps
6 |
7 | Please provide the steps required to reproduce the problem
8 |
9 | 1. Step A
10 |
11 | 2. Step B
12 |
13 | ### Expected behavior
14 |
15 | Please provide a description of the behavior you expect.
16 |
17 | ### Actual behavior
18 |
19 | Please provide a description of the actual behavior you observe.
20 |
21 | ### Known workarounds
22 |
23 | Please provide a description of any known workarounds.
24 |
25 | ### Related information
26 |
27 | * Operating system
28 | * Branch
29 | * .NET Runtime, CoreCLR or Mono Version
30 | * Performance information, links to performance testing scripts
31 |
--------------------------------------------------------------------------------
/.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 | # Xamarin Studio / monodevelop user-specific
10 | *.userprefs
11 |
12 | # Build results
13 |
14 | [Dd]ebug/
15 | [Rr]elease/
16 | x64/
17 | build/
18 | [Bb]in/
19 | [Oo]bj/
20 |
21 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
22 | !packages/*/build/
23 |
24 | # MSTest test Results
25 | [Tt]est[Rr]esult*/
26 | [Bb]uild[Ll]og.*
27 |
28 | *_i.c
29 | *_p.c
30 | *.ilk
31 | *.meta
32 | *.obj
33 | *.pch
34 | *.pdb
35 | *.pgc
36 | *.pgd
37 | *.rsp
38 | *.sbr
39 | *.tlb
40 | *.tli
41 | *.tlh
42 | *.tmp
43 | *.tmp_proj
44 | *.log
45 | *.vspscc
46 | *.vssscc
47 | .builds
48 | *.pidb
49 | *.log
50 | *.scc
51 |
52 | # Visual C++ cache files
53 | ipch/
54 | *.aps
55 | *.ncb
56 | *.opensdf
57 | *.sdf
58 | *.cachefile
59 |
60 | # Visual Studio profiler
61 | *.psess
62 | *.vsp
63 | *.vspx
64 |
65 | # Guidance Automation Toolkit
66 | *.gpState
67 |
68 | # ReSharper is a .NET coding add-in
69 | _ReSharper*/
70 | *.[Rr]e[Ss]harper
71 |
72 | # TeamCity is a build add-in
73 | _TeamCity*
74 |
75 | # DotCover is a Code Coverage Tool
76 | *.dotCover
77 |
78 | # NCrunch
79 | *.ncrunch*
80 | .*crunch*.local.xml
81 |
82 | # Installshield output folder
83 | [Ee]xpress/
84 |
85 | # DocProject is a documentation generator add-in
86 | DocProject/buildhelp/
87 | DocProject/Help/*.HxT
88 | DocProject/Help/*.HxC
89 | DocProject/Help/*.hhc
90 | DocProject/Help/*.hhk
91 | DocProject/Help/*.hhp
92 | DocProject/Help/Html2
93 | DocProject/Help/html
94 |
95 | # Click-Once directory
96 | publish/
97 |
98 | # Publish Web Output
99 | *.Publish.xml
100 |
101 | # Enable nuget.exe in the .nuget folder (though normally executables are not tracked)
102 | !.nuget/NuGet.exe
103 | !.paket/Packet.exe.bootstrapper
104 | .paket/
105 |
106 | # Windows Azure Build Output
107 | csx
108 | *.build.csdef
109 |
110 | # Windows Store app package directory
111 | AppPackages/
112 |
113 | # Others
114 | sql/
115 | *.Cache
116 | ClientBin/
117 | [Ss]tyle[Cc]op.*
118 | ~$*
119 | *~
120 | *.dbmdl
121 | *.[Pp]ublish.xml
122 | *.pfx
123 | *.publishsettings
124 |
125 | # RIA/Silverlight projects
126 | Generated_Code/
127 |
128 | # Backup & report files from converting an old project file to a newer
129 | # Visual Studio version. Backup files are not needed, because we have git ;-)
130 | _UpgradeReport_Files/
131 | Backup*/
132 | UpgradeLog*.XML
133 | UpgradeLog*.htm
134 |
135 | # SQL Server files
136 | App_Data/*.mdf
137 | App_Data/*.ldf
138 |
139 |
140 | #LightSwitch generated files
141 | GeneratedArtifacts/
142 | _Pvt_Extensions/
143 | ModelManifest.xml
144 |
145 | # =========================
146 | # Windows detritus
147 | # =========================
148 |
149 | # Windows image file caches
150 | Thumbs.db
151 | ehthumbs.db
152 |
153 | # Folder config file
154 | Desktop.ini
155 |
156 | # Recycle Bin used on file shares
157 | $RECYCLE.BIN/
158 |
159 | # Mac desktop service store files
160 | .DS_Store
161 |
162 | # ===================================================
163 | # Exclude F# project specific directories and files
164 | # ===================================================
165 |
166 | # NuGet Packages Directory
167 | packages/
168 |
169 | # Generated documentation folder
170 | docs/output/
171 |
172 | # Temp folder used for publishing docs
173 | temp/
174 |
175 | # Test results produced by build
176 | TestResults.xml
177 |
178 | # Nuget outputs
179 | nuget/*.nupkg
180 |
--------------------------------------------------------------------------------
/.nuget/NuGet.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsprojects/FSharp.CloudAgent/4510c97154528efe072bbcd2329301249f66ae1c/.nuget/NuGet.exe
--------------------------------------------------------------------------------
/.paket/paket.bootstrapper.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsprojects/FSharp.CloudAgent/4510c97154528efe072bbcd2329301249f66ae1c/.paket/paket.bootstrapper.exe
--------------------------------------------------------------------------------
/.paket/paket.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | true
6 |
7 | true
8 | $(MSBuildThisFileDirectory)
9 | $(MSBuildThisFileDirectory)..\
10 |
11 |
12 |
13 | $(PaketToolsPath)paket.exe
14 | $(PaketToolsPath)paket.bootstrapper.exe
15 | "$(PaketExePath)"
16 | mono --runtime=v4.0.30319 $(PaketExePath)
17 | "$(PaketBootStrapperExePath)"
18 | mono --runtime=v4.0.30319 $(PaketBootStrapperExePath)
19 |
20 | $(PaketCommand) restore
21 | $(PaketBootStrapperCommand)
22 |
23 | RestorePackages; $(BuildDependsOn);
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 |
3 | env:
4 | matrix:
5 | - MONO_VERSION="3.4.0"
6 |
7 | install:
8 | - wget "http://download.mono-project.com/archive/${MONO_VERSION}/macos-10-x86/MonoFramework-MDK-${MONO_VERSION}.macos10.xamarin.x86.pkg"
9 | - sudo installer -pkg "MonoFramework-MDK-${MONO_VERSION}.macos10.xamarin.x86.pkg" -target /
10 |
11 | script:
12 | - ./build.sh All
13 |
--------------------------------------------------------------------------------
/FSharp.CloudAgent.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 2013
3 | VisualStudioVersion = 12.0.31101.0
4 | MinimumVisualStudioVersion = 10.0.40219.1
5 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{50DF2A1D-B16F-4226-9E32-91999C64DB5D}"
6 | ProjectSection(SolutionItems) = preProject
7 | paket.dependencies = paket.dependencies
8 | paket.lock = paket.lock
9 | EndProjectSection
10 | EndProject
11 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1}"
12 | EndProject
13 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.CloudAgent", "src\FSharp.CloudAgent\FSharp.CloudAgent.fsproj", "{F6147CD2-21E8-41CE-926F-9AB32EAB770D}"
14 | EndProject
15 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "project", "project", "{BF60BC93-E09B-4E5F-9D85-95A519479D54}"
16 | ProjectSection(SolutionItems) = preProject
17 | build.fsx = build.fsx
18 | nuget\FSharp.CloudAgent.nuspec = nuget\FSharp.CloudAgent.nuspec
19 | README.md = README.md
20 | RELEASE_NOTES.md = RELEASE_NOTES.md
21 | EndProjectSection
22 | EndProject
23 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{83F16175-43B1-4C90-A1EE-8E351C33435D}"
24 | ProjectSection(SolutionItems) = preProject
25 | docs\tools\generate.fsx = docs\tools\generate.fsx
26 | docs\tools\templates\template.cshtml = docs\tools\templates\template.cshtml
27 | EndProjectSection
28 | EndProject
29 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "content", "content", "{8E6D5255-776D-4B61-85F9-73C37AA1FB9A}"
30 | ProjectSection(SolutionItems) = preProject
31 | docs\content\agent-paradigms.fsx = docs\content\agent-paradigms.fsx
32 | docs\content\azure-service-bus.fsx = docs\content\azure-service-bus.fsx
33 | docs\content\handling-errors.fsx = docs\content\handling-errors.fsx
34 | docs\content\index.fsx = docs\content\index.fsx
35 | docs\content\tutorial.fsx = docs\content\tutorial.fsx
36 | docs\content\windows-service-bus.fsx = docs\content\windows-service-bus.fsx
37 | EndProjectSection
38 | EndProject
39 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{ED8079DD-2B06-4030-9F0F-DC548F98E1C4}"
40 | EndProject
41 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.CloudAgent.Tests", "tests\FSharp.CloudAgent.Tests\FSharp.CloudAgent.Tests.fsproj", "{E789C72A-5CFD-436B-8EF1-61AA2852A89F}"
42 | EndProject
43 | Global
44 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
45 | Debug|Any CPU = Debug|Any CPU
46 | Release|Any CPU = Release|Any CPU
47 | EndGlobalSection
48 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
49 | {F6147CD2-21E8-41CE-926F-9AB32EAB770D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
50 | {F6147CD2-21E8-41CE-926F-9AB32EAB770D}.Debug|Any CPU.Build.0 = Debug|Any CPU
51 | {F6147CD2-21E8-41CE-926F-9AB32EAB770D}.Release|Any CPU.ActiveCfg = Release|Any CPU
52 | {F6147CD2-21E8-41CE-926F-9AB32EAB770D}.Release|Any CPU.Build.0 = Release|Any CPU
53 | {E789C72A-5CFD-436B-8EF1-61AA2852A89F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
54 | {E789C72A-5CFD-436B-8EF1-61AA2852A89F}.Debug|Any CPU.Build.0 = Debug|Any CPU
55 | {E789C72A-5CFD-436B-8EF1-61AA2852A89F}.Release|Any CPU.ActiveCfg = Release|Any CPU
56 | {E789C72A-5CFD-436B-8EF1-61AA2852A89F}.Release|Any CPU.Build.0 = Release|Any CPU
57 | EndGlobalSection
58 | GlobalSection(SolutionProperties) = preSolution
59 | HideSolutionNode = FALSE
60 | EndGlobalSection
61 | GlobalSection(NestedProjects) = preSolution
62 | {83F16175-43B1-4C90-A1EE-8E351C33435D} = {A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1}
63 | {8E6D5255-776D-4B61-85F9-73C37AA1FB9A} = {A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1}
64 | {E789C72A-5CFD-436B-8EF1-61AA2852A89F} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4}
65 | EndGlobalSection
66 | EndGlobal
67 |
--------------------------------------------------------------------------------
/GenerateDocs.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 | cls
3 |
4 | packages\FAKE\tools\FAKE.exe build.fsx GenerateDocs
5 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | This is free and unencumbered software released into the public domain.
2 |
3 | Anyone is free to copy, modify, publish, use, compile, sell, or
4 | distribute this software, either in source code form or as a compiled
5 | binary, for any purpose, commercial or non-commercial, and by any
6 | means.
7 |
8 | In jurisdictions that recognize copyright laws, the author or authors
9 | of this software dedicate any and all copyright interest in the
10 | software to the public domain. We make this dedication for the benefit
11 | of the public at large and to the detriment of our heirs and
12 | successors. We intend this dedication to be an overt act of
13 | relinquishment in perpetuity of all present and future rights to this
14 | software under copyright law.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
24 | For more information, please refer to
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | FSharp.CloudAgent is a simple framework for making distributed F# Agents in the cloud with the minimum of hassle. See http://fsprojects.github.io/FSharp.CloudAgent/ for full documentation.
2 |
3 |
4 | ## Maintainer(s)
5 |
6 | - [@isaacabraham](https://github.com/isaacabraham)
7 |
8 | The default maintainer account for projects under "fsprojects" is [@fsprojectsgit](https://github.com/fsprojectsgit) - F# Community Project Incubation Space (repo management)
9 |
--------------------------------------------------------------------------------
/RELEASE_NOTES.md:
--------------------------------------------------------------------------------
1 | ### 0.1 - Initial release
2 | * Basic distributed Agents
3 | * Reliable agents backed by Service Bus queues
4 | * Workers Pools
5 | * Actor Pools
6 |
7 | ### 0.2 - Minor enhancements
8 | * Fixed a couple of bugs in resilient agents.
9 |
10 | ### 0.3
11 | * Explicit session abandonment.
12 | * Batch message support.
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | init:
2 | - git config --global core.autocrlf input
3 | build_script:
4 | - cmd: build.cmd
5 | test: off
6 | os: Visual Studio 2017
7 | version: 0.0.1.{build}
8 | artifacts:
9 | - path: bin
10 | name: bin
11 |
--------------------------------------------------------------------------------
/build.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 | cls
3 |
4 | IF NOT EXIST packages\FAKE\tools\FAKE.exe (
5 | .paket\paket.bootstrapper.exe
6 | .paket\paket.exe restore
7 | )
8 |
9 | cd .\src\FSharp.CloudAgent\
10 | dotnet restore
11 | cd ..\..\tests\FSharp.CloudAgent.Tests\
12 | dotnet restore
13 | cd ..\..\
14 |
15 | IF NOT EXIST build.fsx (
16 | packages\FAKE\tools\FAKE.exe init.fsx
17 | )
18 | packages\FAKE\tools\FAKE.exe build.fsx %*
19 |
--------------------------------------------------------------------------------
/build.fsx:
--------------------------------------------------------------------------------
1 | // --------------------------------------------------------------------------------------
2 | // FAKE build script
3 | // --------------------------------------------------------------------------------------
4 |
5 | #r @"packages/FAKE/tools/NuGet.Core.dll"
6 | open Fake.Testing
7 | #r @"packages/FAKE/tools/FakeLib.dll"
8 | open Fake
9 | open Fake.Git
10 | open Fake.AssemblyInfoFile
11 | open Fake.ReleaseNotesHelper
12 | open System
13 | #if MONO
14 | #else
15 | #load "packages/SourceLink.Fake/Tools/Fake.fsx"
16 | open SourceLink
17 | #endif
18 |
19 | let project = "FSharp.CloudAgent"
20 | let summary = "Allows the use of distributed F# Agents in Azure."
21 | let description = "FSharp.CloudAgent provides the capability to run standard F# Agents on top of Azure to allow massively distributed processing of workloads in a resilient manner using Azure Service Bus, either as pools of simple workers or actors."
22 | let authors = [ "Isaac Abraham" ]
23 | let tags = "f# agent actor azure service-bus"
24 | let solutionFile = "FSharp.CloudAgent.sln"
25 | let testAssemblies = "tests/**/bin/Release/net451/*Tests*.dll"
26 | let gitHome = "https://github.com/isaacabraham"
27 | let gitName = "FSharp.CloudAgent"
28 | let gitRaw = environVarOrDefault "gitRaw" "https://raw.github.com/isaacabraham"
29 | Environment.CurrentDirectory <- __SOURCE_DIRECTORY__
30 |
31 |
32 |
33 |
34 |
35 | // Read additional information from the release notes document
36 | let release = parseReleaseNotes (IO.File.ReadAllLines "RELEASE_NOTES.md")
37 |
38 | let genFSAssemblyInfo (projectPath) =
39 | let projectName = System.IO.Path.GetFileNameWithoutExtension(projectPath)
40 | let basePath = "src/" + projectName
41 | let fileName = basePath + "/AssemblyInfo.fs"
42 | CreateFSharpAssemblyInfo fileName
43 | [ Attribute.Title (projectName)
44 | Attribute.Product project
45 | Attribute.Description summary
46 | Attribute.Version release.AssemblyVersion
47 | Attribute.FileVersion release.AssemblyVersion ]
48 |
49 | let genCSAssemblyInfo (projectPath) =
50 | let projectName = System.IO.Path.GetFileNameWithoutExtension(projectPath)
51 | let basePath = "src/" + projectName + "/Properties"
52 | let fileName = basePath + "/AssemblyInfo.cs"
53 | CreateCSharpAssemblyInfo fileName
54 | [ Attribute.Title (projectName)
55 | Attribute.Product project
56 | Attribute.Description summary
57 | Attribute.Version release.AssemblyVersion
58 | Attribute.FileVersion release.AssemblyVersion ]
59 |
60 | // Generate assembly info files with the right version & up-to-date information
61 | Target "AssemblyInfo" (fun _ ->
62 | let fsProjs = !! "src/**/*.fsproj"
63 | let csProjs = !! "src/**/*.csproj"
64 | fsProjs |> Seq.iter genFSAssemblyInfo
65 | csProjs |> Seq.iter genCSAssemblyInfo
66 | )
67 |
68 | // --------------------------------------------------------------------------------------
69 | // Clean build results & restore NuGet packages
70 |
71 | Target "RestorePackages" RestorePackages
72 |
73 | Target "Clean" (fun _ ->
74 | CleanDirs ["bin"; "temp"]
75 | )
76 |
77 | Target "CleanDocs" (fun _ ->
78 | CleanDirs ["docs/output"]
79 | )
80 |
81 | // --------------------------------------------------------------------------------------
82 | // Build library & test project
83 |
84 | Target "Build" (fun _ ->
85 | !! solutionFile
86 | |> MSBuildRelease "" "Rebuild"
87 | |> ignore
88 | )
89 |
90 | // --------------------------------------------------------------------------------------
91 | // Run the unit tests using test runner
92 |
93 | Target "RunTests" (fun _ ->
94 | !! testAssemblies
95 | |> NUnit3 (fun p ->
96 | { p with
97 | ShadowCopy = true
98 | TimeOut = TimeSpan.FromMinutes 20. })
99 | )
100 |
101 | #if MONO
102 | #else
103 | // --------------------------------------------------------------------------------------
104 | // SourceLink allows Source Indexing on the PDB generated by the compiler, this allows
105 | // the ability to step through the source code of external libraries https://github.com/ctaggart/SourceLink
106 |
107 | Target "SourceLink" (fun _ ->
108 | let baseUrl = sprintf "%s/%s/{0}/%%var2%%" gitRaw (project.ToLower())
109 | use repo = new GitRepo(__SOURCE_DIRECTORY__)
110 | !! "src/**/*.fsproj"
111 | |> Seq.iter (fun f ->
112 | let proj = VsProj.LoadRelease f
113 | logfn "source linking %s" proj.OutputFilePdb
114 | let files = proj.Compiles -- "**/AssemblyInfo.fs"
115 | repo.VerifyChecksums files
116 | proj.VerifyPdbChecksums files
117 | proj.CreateSrcSrv baseUrl repo.Revision (repo.Paths files)
118 | Pdbstr.exec proj.OutputFilePdb proj.OutputFilePdbSrcSrv
119 | )
120 | )
121 | #endif
122 |
123 | // --------------------------------------------------------------------------------------
124 | // Build a NuGet package
125 |
126 | let asDependency name = name, GetPackageVersion "packages" name
127 |
128 | Target "NuGet" (fun _ ->
129 | NuGet (fun p ->
130 | { p with
131 | Authors = authors
132 | Project = project
133 | Summary = summary
134 | Description = description
135 | Version = release.NugetVersion
136 | ReleaseNotes = String.Join(Environment.NewLine, release.Notes)
137 | Tags = tags
138 | OutputPath = "bin"
139 | AccessKey = getBuildParamOrDefault "nugetkey" ""
140 | Publish = hasBuildParam "nugetkey"
141 | Dependencies = [ "WindowsAzure.ServiceBus"
142 | "Newtonsoft.Json" ] |> List.map asDependency })
143 | ("nuget/" + project + ".nuspec")
144 | )
145 |
146 | // --------------------------------------------------------------------------------------
147 | // Generate the documentation
148 |
149 | Target "GenerateReferenceDocs" (fun _ ->
150 | if not <| executeFSIWithArgs "docs/tools" "generate.fsx" ["--define:RELEASE"; "--define:REFERENCE"] [] then
151 | failwith "generating reference documentation failed"
152 | )
153 |
154 | Target "GenerateHelp" (fun _ ->
155 | if not <| executeFSIWithArgs "docs/tools" "generate.fsx" ["--define:RELEASE"; "--define:HELP"] [] then
156 | failwith "generating help documentation failed"
157 | )
158 |
159 | Target "GenerateDocs" DoNothing
160 |
161 | // --------------------------------------------------------------------------------------
162 | // Release Scripts
163 |
164 | Target "ReleaseDocs" (fun _ ->
165 | let tempDocsDir = "temp/gh-pages"
166 | CleanDir tempDocsDir
167 | Repository.cloneSingleBranch "" (gitHome + "/" + gitName + ".git") "gh-pages" tempDocsDir
168 |
169 | CopyRecursive "docs/output" tempDocsDir true |> tracefn "%A"
170 | StageAll tempDocsDir
171 | Commit tempDocsDir (sprintf "Update generated documentation for version %s" release.NugetVersion)
172 | Branches.push tempDocsDir
173 | )
174 |
175 | Target "Release" (fun _ ->
176 | StageAll ""
177 | Commit "" (sprintf "Bump version to %s" release.NugetVersion)
178 | Branches.push ""
179 |
180 | Branches.tag "" release.NugetVersion
181 | Branches.pushTag "" "origin" release.NugetVersion
182 | )
183 |
184 | Target "BuildPackage" DoNothing
185 |
186 | // --------------------------------------------------------------------------------------
187 | // Run all targets by default. Invoke 'build ' to override
188 |
189 | Target "All" DoNothing
190 |
191 | "Clean"
192 | ==> "RestorePackages"
193 | ==> "AssemblyInfo"
194 | ==> "Build"
195 | ==> "RunTests"
196 | =?> ("GenerateReferenceDocs",isLocalBuild && not isMono)
197 | =?> ("GenerateDocs",isLocalBuild && not isMono)
198 | ==> "All"
199 | =?> ("ReleaseDocs",isLocalBuild && not isMono)
200 |
201 | "All"
202 | #if MONO
203 | #else
204 | =?> ("SourceLink", Pdbstr.tryFind().IsSome )
205 | #endif
206 | ==> "NuGet"
207 | ==> "BuildPackage"
208 |
209 | "CleanDocs"
210 | ==> "GenerateHelp"
211 | ==> "GenerateReferenceDocs"
212 | ==> "GenerateDocs"
213 |
214 | "ReleaseDocs"
215 | ==> "Release"
216 |
217 | "BuildPackage"
218 | ==> "Release"
219 |
220 | RunTargetOrDefault "All"
221 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | if test "$OS" = "Windows_NT"
3 | then
4 | # use .Net
5 | .nuget/NuGet.exe install FAKE -OutputDirectory packages -ExcludeVersion
6 | .nuget/NuGet.exe install SourceLink.Fake -OutputDirectory packages -ExcludeVersion
7 | [ ! -e build.fsx ] && packages/FAKE/tools/FAKE.exe init.fsx
8 | packages/FAKE/tools/FAKE.exe build.fsx $@
9 | else
10 | # use mono
11 | mono .nuget/NuGet.exe install FAKE -OutputDirectory packages -ExcludeVersion
12 | mono .nuget/NuGet.exe install SourceLink.Fake -OutputDirectory packages -ExcludeVersion
13 | [ ! -e build.fsx ] && mono packages/FAKE/tools/FAKE.exe init.fsx
14 | mono packages/FAKE/tools/FAKE.exe $@ --fsiargs -d:MONO build.fsx
15 | fi
16 |
--------------------------------------------------------------------------------
/docs/content/agent-paradigms.fsx:
--------------------------------------------------------------------------------
1 | (**
2 | Agent Paradigms
3 | ===============
4 | This article briefly explains the two distributed agent models supported by CloudAgent.
5 |
6 | Agent types
7 | -----------
8 | Different types of agents control the manner in which messages are passed through your
9 | application as well as the sizing behaviour of the pools themselves.
10 | ### Worker Pools
11 | Worker Pools represent agents which are entirely stateless. They can handle messages
12 | in any order and at any time. Worker Pools in CloudAgent are fixed at a size of 512 workers
13 | per node; messages will be randomly distributed through the worker pool. You will probably
14 | use Workers for the majority of your distributed workloads.
15 | ### Actor Pools
16 | Actor Pools represent agents which activate and deactive as work appears for them to
17 | process. Messages are "routed" to a specific agent by means of an ActorKey - a simple
18 | string which is used to determine which agent will receive the message. Each CloudAgent
19 | node maintains a set of agents which will be created and destroyed as required to fulfil
20 | requests for a specific actor. Thus, whilst an actor pool is theoretically unlimited in size,
21 | the actual number of Actors running at any given time is equal to the number of messages
22 | being processed, grouped by ActorKey.
23 | As both Service Bus sessions and F# Agents naturally guarantee sequential flow of messages,
24 | Actor Pools can be used in situations where you do not want to worry about concurrent processing
25 | of messages. This can be used to dramatically simplify your software at the cost of removing
26 | parallelisation of processing for messages keyed to the same actor.
27 | ### Hybrid Models
28 | There is nothing to stop you sharing agent code across both types of agent pools. You can send
29 | some messages over a standard Service Bus Queue for worker-style processing, and send
30 | other messages that you need to run in isolation over a sessionised queue for Actor processing.
31 |
32 | Agent Resiliency
33 | ----------------
34 | Agents can handle messages in different ways to cope with errors. CloudAgent offers two different
35 | models.
36 | ### Basic Agents
37 | Basic agents are the most simple to create - you simply bind your existing F# Agent code
38 | to a service bus queue. When messages arrive from the service bus, once they have been
39 | successfully deserialised, CloudAgent will dispatch the to an agent for processing and
40 | immediately mark them as complete on the service bus.
41 | This is the simplest model for processing and means that your agents will never receive
42 | the same message more than once. However, it is entirely your responsibility to handle
43 | retry logic of messages which fail, or to log messages which cannot be processed. If
44 | your agent crashes, or Azure decides to restart the machine on which your agent pool is
45 | running on whilst processing a message, that message will be lost.
46 | You might use Basic Agents when creating pools where failing to completely process a single
47 | message is not critical to the overall operation of your application.
48 | ### Resilient Agents
49 | Resilient Agents use the built-in capabilities of Azure Service Bus to guarantee message
50 | processing, with built-in retry logic and dead lettering. Rather than simply receiving a
51 | message and processing them, your F# Agents receive both a message and a reply channel.
52 | Once your agent finishes processing a message, it should reply back with a status
53 | (Completed, Failed or Abandon), which in turn is converted into a Service Bus message
54 | acknowledgement. Only when Service Bus receives this acknowledge will it remove the message
55 | from the queue. Otherwise, if your Agent crashes or fails to reply within the message timeout
56 | period, Service Bus will once again make the message available for other nodes to consume.
57 | Messages that repeatedly fail will automatically be pushed to a dead letter queue on the
58 | service bus where they can be analysed in isolation.
59 | In this model, messages are guaranteed to be delivered at least once to an agent for
60 | processing. Use this model where you need to guarantee delivery of every message in the
61 | system to your agents and need resliency of message processing.
62 | *)
--------------------------------------------------------------------------------
/docs/content/azure-service-bus.fsx:
--------------------------------------------------------------------------------
1 | (**
2 | About Azure Service Bus
3 | =======================
4 | This article is not meant to replace the reams of documentation available on [Azure] [azure-service-bus]
5 | or [MSDN] [msdn-service-bus], but give a quick guide on how to get up an running with
6 | service bus for the purposes of FSharp.CloudAgent, and how to map Azure Service Bus
7 | concepts to F# Agents.
8 |
9 | Note: if you do not want to use Azure, you can self-host using the [Windows Service Bus](windows-service-bus.html). Read through
10 | this article first as the principles are the same, and then read that one for installation guidance.
11 |
12 | Azure Service Bus Overview
13 | --------------------------
14 | Azure Service Bus provides a simple and cheap distributed messaging framework that runs
15 | in the Azure cloud. It comes in several flavours - the part that CloudAgent harnesses is
16 | that of [Service Bus Queues] [service-bus-queues], which provides reliable messaging
17 | through storage-backed queues in Azure that can have multiple consumers. In the context
18 | of CloudAgent, each consumer is a worker node i.e. .NET process that runs a number of
19 | F# agents to process messages. CloudAgent manages the lifetime of agents as needed,
20 | handing out messages as they arrive to the agent pool for processing, as well as relaying
21 | completion messages back to the Service Bus from agents.
22 |
23 | Service Bus Queues key concepts
24 | -------------------------------
25 | Within the context of CloudAgent, Service Bus Queues provide the following key features: -
26 |
27 | * **Reliable**. Service Bus Queues guarantee message *delivery to* and *processing by* consumers.
28 | If a message is not completed within a specified timeout, it is made available for processing
29 | again by another consumer. Thus, distributed message processing in CloudAgent takes the form
30 | of *at-least-once* processing; a message will be processed *at least once*, but depending on
31 | whether the consumer successfully "completes" the message, it may be re-processed by other
32 | consumers. Your agents should be written to handle messages in an idempotent manner, or at
33 | least detect repeat messages.
34 | * **High throughput**. Supports up to 2k messages / sec per queue, with average latency of
35 | 20-25ms.
36 | * **Cheap**. $0.01 per 10k messages.
37 | * **Sessionised**. Service Bus Queues provide the ability to ensure sequential delivery of
38 | messages that are partitioned based on an arbitrary "SessionId". This forms the basis of
39 | Actor support within CloudAgent; an ActorKey is mapped to the SessionId of individual
40 | messages, thus ensuring that messages for the same Actor are delivered to the same consumer
41 | in sequence.
42 |
43 | How to create a Service Bus Queue
44 | ---------------------------------
45 | Follow the guidance [here] [service-bus-queues] to create a new service bus namespace.
46 | Once the namespace is created, you can generate a Queue through Visual Studio or in code.
47 |
48 |
49 |
50 |
51 | It is important to understand that for Actor pools, you *must* turn on Session support
52 | when creating the queue; likewise for Worker pools, Session support must be turned *off*.
53 |
54 | [azure-service-bus]: http://azure.microsoft.com/en-us/services/service-bus/
55 | [msdn-service-bus]: http://msdn.microsoft.com/en-us/library/azure/ee732537.aspx
56 | [service-bus-queues]: http://azure.microsoft.com/en-us/documentation/articles/service-bus-dotnet-how-to-use-queues/
57 | *)
--------------------------------------------------------------------------------
/docs/content/handling-errors.fsx:
--------------------------------------------------------------------------------
1 | (**
2 | Handling Errors
3 | ===============
4 | Your approach towards error handling will most likely differ depending on the type of agent
5 | pool (irrespective of whether worker or actor) being used.
6 | Basic Agents
7 | ------------
8 | Basic agents work on an "at-most-once" delivery mechanism to F# agents. This means that it is
9 | entirely your responsibility to be able to guarantee processing of these messages. You should
10 | cater for logging out failures as well as persisting failed messages to some persistance store
11 | for later inspection. If an agent crashes due to an unhandled exception, your message will be
12 | lost permanently.
13 | Resilient Agents
14 | ----------------
15 | Reslient agents work on an "at-least-once" delivery mechanism. Failed messages will automatically
16 | be redelivered until the queue marks them as dead lettered. If an agent crashes due to an unhandled
17 | exception, your message will be automatically re-delivered once it expires. If you set this expiry
18 | too long, you may wish to consider wrapping your agent processing code in a try catch or other
19 | exception handling pattern and immediately returning a Failed to the CloudAgent framework to short-
20 | circuit this wait.
21 | *)
--------------------------------------------------------------------------------
/docs/content/index.fsx:
--------------------------------------------------------------------------------
1 | (**
2 | About FSharp.CloudAgent
3 | =======================
4 |
5 | FSharp.CloudAgent provides a simple framework to easily distribute workloads over the cloud
6 | whilst using standard F# Agents as the processing mechanism. Support exists for both simple
7 | and reliable messaging via Azure Service Bus, and for both workers and actors.
8 |
9 | Samples & documentation
10 | -----------------------
11 |
12 | The library comes with comprehensible documentation. The API reference is automatically
13 | generated from Markdown comments in the library implementation.
14 |
15 | * [Tutorial](tutorial.html) contains same basic examples of how to use FSharp.CloudAgent.
16 | * [Agent Paradigms](agent-paradigms.html) explains the core differences between the types of supported Cloud Agents.
17 | * [Azure Service Bus](azure-service-bus.html) provides an overview of Azure Service Bus and how it interoperates with F# Agents.
18 | * [Windows Service Bus](windows-service-bus.html) provides an overview of Windows Service Bus and how it can be used in place of Azure Service Bus.
19 | * [Error Handling](handling-errors.html) suggests some high-level principles of how to cater for errors within Cloud Agent.
20 | * [API Reference](reference/index.html) contains automatically generated documentation for all types, modules
21 | and functions in the library. This includes additional brief samples on using most of the
22 | functions.
23 |
24 | Contributing and copyright
25 | --------------------------
26 |
27 | The project is hosted on [GitHub][gh] where you can [report issues][issues], fork
28 | the project and submit pull requests. If you're adding a new public API, please also
29 | consider adding [samples][content] that can be turned into a documentation. You might
30 | also want to read the [library design notes][readme] to understand how it works.
31 |
32 | The library is available under Public Domain license, which allows modification and
33 | redistribution for both commercial and non-commercial purposes. For more information see the
34 | [License file][license] in the GitHub repository.
35 |
36 | [content]: https://github.com/isaacabraham/FSharp.CloudAgent/tree/master/docs/content
37 | [gh]: https://github.com/isaacabraham/FSharp.CloudAgent
38 | [issues]: https://github.com/isaacabraham/FSharp.CloudAgent/issues
39 | [readme]: https://github.com/isaacabraham/FSharp.CloudAgent/blob/master/README.md
40 | [license]: https://github.com/isaacabraham/FSharp.CloudAgent/blob/master/LICENSE.txt
41 | *)
42 |
--------------------------------------------------------------------------------
/docs/content/tutorial.fsx:
--------------------------------------------------------------------------------
1 | (*** hide ***)
2 | #r @"..\..\bin\FSharp.CloudAgent.dll"
3 |
4 | (**
5 | Tutorial
6 | ============
7 | Getting up and running
8 | ----------------------
9 | Creating a simple distributable Agent is as simple as creating a regular agent, wrapping it
10 | in a generator function and then binding that function to a service bus queue.
11 |
12 | *)
13 |
14 | open FSharp.CloudAgent
15 | open FSharp.CloudAgent.Messaging
16 | open FSharp.CloudAgent.Connections
17 |
18 | // Standard Azure Service Bus connection string
19 | let serviceBusConnection = ServiceBusConnection "servicebusconnectionstringgoeshere"
20 |
21 | // A DTO
22 | type Person = { Name : string; Age : int }
23 |
24 | // A function which creates an Agent on demand.
25 | let createASimpleAgent agentId =
26 | MailboxProcessor.Start(fun inbox ->
27 | async {
28 | while true do
29 | let! message = inbox.Receive()
30 | printfn "%s is %d years old." message.Name message.Age
31 | })
32 |
33 | // Create a worker cloud connection to the Service Bus Queue "myMessageQueue"
34 | let cloudConnection = WorkerCloudConnection(serviceBusConnection, Queue "myMessageQueue")
35 |
36 | // Start listening! A local pool of agents will be created that will receive messages.
37 | // Service bus messages will be automatically deserialised into the required message type.
38 | ConnectionFactory.StartListening(cloudConnection, createASimpleAgent >> BasicCloudAgent)
39 |
40 |
41 | (**
42 |
43 | Posting messages to agents
44 | --------------------------
45 | You can elect to natively send messages to the service bus (as long as the serialisation
46 | format matches i.e. JSON .NET). However, FSharp.CloudAgent includes some handy helper functions
47 | to do this for you.
48 |
49 | *)
50 |
51 | let sendToMyMessageQueue = ConnectionFactory.SendToWorkerPool cloudConnection
52 |
53 | // These messages will be processed in parallel across the worker pool.
54 | sendToMyMessageQueue { Name = "Isaac"; Age = 34 }
55 | sendToMyMessageQueue { Name = "Michael"; Age = 32 }
56 | sendToMyMessageQueue { Name = "Sam"; Age = 27 }
57 |
58 | (**
59 |
60 | Creating Resilient Agents
61 | -------------------------
62 | We can also create "Resilient" agents. These are standard F# Agents that take advantage of the
63 | Reply Channel functionality inherent in F# agents to allow us to signal back to Azure whether
64 | or not a message was processed correctly or not, which in turn gives us automatic retry and dead
65 | letter functionality that is included with Azure Service Bus.
66 |
67 | *)
68 |
69 | // A function which creates a Resilient Agent on demand.
70 | let createAResilientAgent agentId =
71 | MailboxProcessor.Start(fun inbox ->
72 | async {
73 | while true do
74 | let! message, replyChannel = inbox.Receive()
75 | printfn "%s is %d years old." message.Name message.Age
76 |
77 | match message with
78 | | { Name = "Isaac" } -> replyChannel Completed // all good, message was processed
79 | | { Name = "Richard" } -> replyChannel Failed // error occurred, try again
80 | | _ -> replyChannel Abandoned // give up with this message.
81 | })
82 |
83 | // Start listening! A local pool of agents will be created that will receive messages.
84 | ConnectionFactory.StartListening(cloudConnection, createAResilientAgent >> ResilientCloudAgent)
85 |
86 | (**
87 |
88 | Creating distributed Actors
89 | ---------------------------
90 | In addition to the massively distributable messages seen above, we can also create agents which are
91 | threadsafe not only within the context of a process but also in the context of multiple processes on
92 | different machines. This is made possible by Azure Service Bus session support. To turn an agent into
93 | an actor, we simply change the connection and the way in which we post messages.
94 |
95 | *)
96 |
97 | // Create an actor cloud connection to the Service Bus Queue "myActorQueue". This queue must have
98 | // Session support turned on.
99 | let actorConnection = ActorCloudConnection(serviceBusConnection, Queue "myActorQueue")
100 |
101 | // Start listening! Agents will be created as required for messages sent to new actors.
102 | ConnectionFactory.StartListening(actorConnection, createASimpleAgent >> BasicCloudAgent)
103 |
104 | // Send some messages to the actor pool
105 | let sendToMyActorQueue = ConnectionFactory.SendToActorPool actorConnection
106 |
107 | let sendToFred = sendToMyActorQueue (ActorKey "Fred")
108 | let sendToMax = sendToMyActorQueue (ActorKey "Max")
109 |
110 | // The first two messages will be sent in sequence to the same agent in the same process.
111 | // The last message will be sent to a different agent, potentially in another process.
112 | sendToFred { Name = "Isaac"; Age = 34 }
113 | sendToFred { Name = "Michael"; Age = 32 }
114 | sendToMax { Name = "Sam"; Age = 27 }
--------------------------------------------------------------------------------
/docs/content/windows-service-bus.fsx:
--------------------------------------------------------------------------------
1 | (**
2 | About Windows Service Bus
3 | =======================
4 | Windows Service Bus (WSB) can be thought of as an on-premises version of Azure Service
5 | Bus. As such, everything mentioned in the [Azure Service Bus](azure-service-bus.html) section still holds true
6 | in terms of operations and application within Cloud Agent. The difference with WSB is
7 | that you manage the service bus yourself on your network, and can host all entire
8 | internally on your network. This article will provide some simple instructions on
9 | installation of Windows Service Bus that will enable you to use Cloud Agent without
10 | using Azure.
11 |
12 | Windows Service Bus versions
13 | ----------------------------
14 | WSB currently comes in two versions - 1.0 and 1.1. Whilst 1.0 at the current time of
15 | writing is supported natively in Visual Studio 2013, 1.1 is not. However, WSB 1.1
16 | brings a raft of [features] [wsb-11] that bring it up to parity with the 2.x SDK of Azure Service
17 | Bus. As such, WSB 1.1 is recommended for use with Cloud Agent.
18 |
19 | Windows Service Bus Installation
20 | --------------------------------
21 | Full details can be found [here] [install-wsb]. Essentially, you install the WSB service, which stores data
22 | in a SQL database. This can be full SQL Server or SQL Server Express (indeed, you can even
23 | install it on LocalDB).
24 |
25 | Managing WSB
26 | ------------
27 | Unlike Azure Service Bus, you cannot use the Azure Portal to manage a locally hosted
28 | Windows Service Bus. Instead, there are several ways to interact with WSB: -
29 |
30 | * You can use the existing Service Bus SDK to programmatically create queues etc. having
31 | connected to the local service bus.
32 | * You can use the [Service Bus Explorer] [sb-exp] tool. Note that only version 2.1 is
33 | compatible with WSB 1.1. The latest version (2.5.3) does NOT support WSB 1.1.
34 | * You can use the [Service Bus Powershell cmdlets] [sb-psh] to perform basic interrogation
35 | of your service bus farm.
36 |
37 | WSB Connection Strings
38 | ----------------------
39 | Connection strings on WSB are similar to those on Azure Service Bus.
40 |
41 | 1. You can identify the default namespace using the ``get-sbNamespace`` cmdlet.
42 | 2. You can generate a connection string using the ``get-sbClientConfiguration`` cmdlet.
43 |
44 | This connection string can be used directly in place of the standard Azure Service Bus
45 | connection string in CloudAgent. Your application code remains unchanged.
46 |
47 | [wsb-11]: http://msdn.microsoft.com/en-us/library/dn282143.aspx
48 | [install-wsb]: http://msdn.microsoft.com/en-us/library/dn282152.aspx
49 | [sb-exp]: https://code.msdn.microsoft.com/windowsapps/Service-Bus-Explorer-f2abca5a
50 | [sb-psh]: http://msdn.microsoft.com/en-us/library/jj200653%28v=azure.10%29.aspx
51 | *)
--------------------------------------------------------------------------------
/docs/files/img/create-a-queue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsprojects/FSharp.CloudAgent/4510c97154528efe072bbcd2329301249f66ae1c/docs/files/img/create-a-queue.png
--------------------------------------------------------------------------------
/docs/files/img/logo-template.pdn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsprojects/FSharp.CloudAgent/4510c97154528efe072bbcd2329301249f66ae1c/docs/files/img/logo-template.pdn
--------------------------------------------------------------------------------
/docs/files/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsprojects/FSharp.CloudAgent/4510c97154528efe072bbcd2329301249f66ae1c/docs/files/img/logo.png
--------------------------------------------------------------------------------
/docs/files/img/queues-in-vs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsprojects/FSharp.CloudAgent/4510c97154528efe072bbcd2329301249f66ae1c/docs/files/img/queues-in-vs.png
--------------------------------------------------------------------------------
/docs/tools/generate.fsx:
--------------------------------------------------------------------------------
1 | // --------------------------------------------------------------------------------------
2 | // Builds the documentation from `.fsx` and `.md` files in the 'docs/content' directory
3 | // (the generated documentation is stored in the 'docs/output' directory)
4 | // --------------------------------------------------------------------------------------
5 |
6 | // Binaries that have XML documentation (in a corresponding generated XML file)
7 | let referenceBinaries = [ "FSharp.CloudAgent.dll" ]
8 | // Web site location for the generated documentation
9 | let website = "/FSharp.CloudAgent"
10 |
11 | let githubLink = "http://github.com/isaacabraham/FSharp.CloudAgent"
12 |
13 | // Specify more information about your project
14 | let info =
15 | [ "project-name", "FSharp.CloudAgent"
16 | "project-author", "Isaac Abraham"
17 | "project-summary", "Allows the use of F# Agents in Azure."
18 | "project-github", githubLink
19 | "project-nuget", "http://nuget.org/packages/FSharp.CloudAgent" ]
20 |
21 | // --------------------------------------------------------------------------------------
22 | // For typical project, no changes are needed below
23 | // --------------------------------------------------------------------------------------
24 |
25 | #I "../../packages/FSharp.Formatting/lib/net40"
26 | #I "../../packages/RazorEngine/lib/net40"
27 | #I "../../packages/FSharp.Compiler.Service/lib/net40"
28 | #r "../../packages/Microsoft.AspNet.Razor/lib/net40/System.Web.Razor.dll"
29 | #r "../../packages/FAKE/tools/NuGet.Core.dll"
30 | #r "../../packages/FAKE/tools/FakeLib.dll"
31 | #r "RazorEngine.dll"
32 | #r "FSharp.Literate.dll"
33 | #r "FSharp.CodeFormat.dll"
34 | #r "FSharp.MetadataFormat.dll"
35 | open Fake
36 | open System.IO
37 | open Fake.FileHelper
38 | open FSharp.Literate
39 | open FSharp.MetadataFormat
40 |
41 | // When called from 'build.fsx', use the public project URL as
42 | // otherwise, use the current 'output' directory.
43 | #if RELEASE
44 | let root = website
45 | #else
46 | let root = "file://" + (__SOURCE_DIRECTORY__ @@ "../output")
47 | #endif
48 |
49 | // Paths with template/source/output locations
50 | let bin = __SOURCE_DIRECTORY__ @@ "../../bin"
51 | let content = __SOURCE_DIRECTORY__ @@ "../content"
52 | let output = __SOURCE_DIRECTORY__ @@ "../output"
53 | let files = __SOURCE_DIRECTORY__ @@ "../files"
54 | let templates = __SOURCE_DIRECTORY__ @@ "templates"
55 | let formatting = __SOURCE_DIRECTORY__ @@ "../../packages/FSharp.Formatting/"
56 | let docTemplate = formatting @@ "templates/docpage.cshtml"
57 |
58 | // Where to look for *.csproj templates (in this order)
59 | let layoutRoots =
60 | [ templates; formatting @@ "templates"
61 | formatting @@ "templates/reference" ]
62 |
63 | // Copy static files and CSS + JS from F# Formatting
64 | let copyFiles () =
65 | CopyRecursive files output true |> Log "Copying file: "
66 | ensureDirectory (output @@ "content")
67 | CopyRecursive (formatting @@ "styles") (output @@ "content") true
68 | |> Log "Copying styles and scripts: "
69 |
70 | // Build API reference from XML comments
71 | let buildReference () =
72 | CleanDir (output @@ "reference")
73 | let binaries =
74 | referenceBinaries
75 | |> List.map (fun lib-> bin @@ lib)
76 | MetadataFormat.Generate
77 | ( binaries, output @@ "reference", layoutRoots,
78 | parameters = ("root", root)::info,
79 | sourceRepo = githubLink @@ "tree/master",
80 | sourceFolder = __SOURCE_DIRECTORY__ @@ ".." @@ "..",
81 | publicOnly = true )
82 |
83 | // Build documentation from `fsx` and `md` files in `docs/content`
84 | let buildDocumentation () =
85 | let subdirs = Directory.EnumerateDirectories(content, "*", SearchOption.AllDirectories)
86 | for dir in Seq.append [content] subdirs do
87 | let sub = if dir.Length > content.Length then dir.Substring(content.Length + 1) else "."
88 | Literate.ProcessDirectory
89 | ( dir, docTemplate, output @@ sub, replacements = ("root", root)::info,
90 | layoutRoots = layoutRoots )
91 |
92 | // Generate
93 | copyFiles()
94 | #if HELP
95 | buildDocumentation()
96 | #endif
97 | #if REFERENCE
98 | buildReference()
99 | #endif
100 |
--------------------------------------------------------------------------------
/docs/tools/paket.references:
--------------------------------------------------------------------------------
1 | FSharp.Formatting
2 | FSharp.Compiler.Service
3 | Microsoft.AspNet.Razor
4 | RazorEngine
--------------------------------------------------------------------------------
/docs/tools/templates/template.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | @Title
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |