From b0093505be97ed9bdbe71a275a7f3326da73f3fa Mon Sep 17 00:00:00 2001 From: ereali-aneo <ereali@aneo.fr> Date: Wed, 10 Jul 2024 14:42:12 +0200 Subject: [PATCH] chores: add code format in github workflow --- .editorconfig | 164 +++++++++++ .github/workflows/code-formatting.yml | 57 ++++ ArmoniK.TaskReRunner.sln | 2 +- ArmoniK.TaskReRunner.sln.DotSettings | 38 +++ src/TaskReRunner/Agent.cs | 211 ++++++++++++++ src/TaskReRunner/MyAgent.cs | 206 -------------- src/TaskReRunner/Program.cs | 385 ++++++++++++++------------ src/TaskReRunner/Server.cs | 161 ++++++----- src/TaskReRunner/Utils.cs | 105 ++++--- 9 files changed, 829 insertions(+), 500 deletions(-) create mode 100644 .editorconfig create mode 100644 .github/workflows/code-formatting.yml create mode 100644 ArmoniK.TaskReRunner.sln.DotSettings create mode 100644 src/TaskReRunner/Agent.cs delete mode 100644 src/TaskReRunner/MyAgent.cs diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..3a0c4f2 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,164 @@ +root = true + +[*.{appxmanifest,axaml,axml,build,c,config,cs,csproj,cpp,dbml,discomap,dtd,html,js,json,jsproj,lsproj,md,njsproj,nuspec,paml,proj,props,proto,resjson,StyleCop,targets,tasks,vbproj,xaml,xamlx,xml,xoml,xsd}] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +indent_style = space +indent_size = 2 +tab_width = 2 + + +[*] +# Microsoft .NET properties +csharp_preferred_modifier_order = public, private, protected, internal, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async:suggestion +csharp_space_after_cast = false +csharp_style_expression_bodied_accessors = true:suggestion +csharp_style_expression_bodied_constructors = true:none +csharp_style_expression_bodied_methods = true:none +csharp_style_expression_bodied_properties = true:suggestion +csharp_style_var_elsewhere = true:suggestion +csharp_style_var_for_built_in_types = true:suggestion +csharp_style_var_when_type_is_apparent = true:suggestion +dotnet_naming_rule.private_constants_rule.import_to_resharper = as_predefined +dotnet_naming_rule.private_constants_rule.severity = warning +dotnet_naming_rule.private_constants_rule.style = upper_camel_case_style +dotnet_naming_rule.private_constants_rule.symbols = private_constants_symbols +dotnet_naming_rule.private_instance_fields_rule.import_to_resharper = as_predefined +dotnet_naming_rule.private_instance_fields_rule.severity = warning +dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case__style +dotnet_naming_rule.private_instance_fields_rule.symbols = private_instance_fields_symbols +dotnet_naming_rule.private_static_fields_rule.import_to_resharper = as_predefined +dotnet_naming_rule.private_static_fields_rule.severity = warning +dotnet_naming_rule.private_static_fields_rule.style = lower_camel_case_style +dotnet_naming_rule.private_static_fields_rule.symbols = private_static_fields_symbols +dotnet_naming_rule.private_static_readonly_rule.import_to_resharper = as_predefined +dotnet_naming_rule.private_static_readonly_rule.severity = warning +dotnet_naming_rule.private_static_readonly_rule.style = upper_camel_case_style +dotnet_naming_rule.private_static_readonly_rule.symbols = private_static_readonly_symbols +dotnet_naming_style.lower_camel_case_style.capitalization = camel_case +dotnet_naming_style.lower_camel_case_style.required_prefix = _ +dotnet_naming_style.lower_camel_case__style.capitalization = camel_case +dotnet_naming_style.lower_camel_case__style.required_suffix = _ +dotnet_naming_style.upper_camel_case_style.capitalization = pascal_case +dotnet_naming_symbols.private_constants_symbols.applicable_accessibilities = private +dotnet_naming_symbols.private_constants_symbols.applicable_kinds = field +dotnet_naming_symbols.private_constants_symbols.required_modifiers = const +dotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities = private +dotnet_naming_symbols.private_instance_fields_symbols.applicable_kinds = field +dotnet_naming_symbols.private_static_fields_symbols.applicable_accessibilities = private +dotnet_naming_symbols.private_static_fields_symbols.applicable_kinds = field +dotnet_naming_symbols.private_static_fields_symbols.required_modifiers = static +dotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities = private +dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field +dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers = static, readonly +dotnet_separate_import_directive_groups = true +dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:none +dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none +dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion +dotnet_style_predefined_type_for_member_access = true:suggestion +dotnet_style_qualification_for_event = false:suggestion +dotnet_style_qualification_for_field = false:suggestion +dotnet_style_qualification_for_method = false:suggestion +dotnet_style_qualification_for_property = false:suggestion +dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion +file_header_template = This file is part of the ArmoniK project\n\nCopyright (C) ANEO, 2021-$CURRENT_YEAR$. All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the "License")\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an "AS IS" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n + +# diagnostics +dotnet_diagnostic.ca2213.severity = error + +# IDE0018: Inline variable declaration +csharp_style_inlined_variable_declaration = false + +# ReSharper properties +resharper_align_linq_query = true +resharper_align_multiline_argument = true +resharper_align_multiline_array_and_object_initializer = true +resharper_align_multiline_binary_patterns = true +resharper_align_multiline_calls_chain = true +resharper_align_multiline_expression = true +resharper_align_multiline_for_stmt = true +resharper_align_multiline_property_pattern = true +resharper_align_multiline_switch_expression = true +resharper_align_multline_type_parameter_constrains = true +resharper_align_multline_type_parameter_list = true +resharper_align_tuple_components = true +resharper_braces_for_for = required +resharper_braces_for_foreach = required +resharper_braces_for_ifelse = required +resharper_braces_for_using = required +resharper_braces_for_while = required +resharper_csharp_align_first_arg_by_paren = true +resharper_csharp_align_multiline_parameter = true +resharper_csharp_align_multiple_declaration = true +resharper_csharp_allow_far_alignment = true +resharper_csharp_indent_size = 2 +resharper_csharp_insert_final_newline = true +resharper_csharp_max_line_length = 169 +resharper_csharp_naming_rule.private_constants = AaBb +resharper_csharp_naming_rule.private_static_fields = _ + aaBb +resharper_csharp_naming_rule.private_static_readonly = AaBb +resharper_csharp_outdent_commas = true +resharper_csharp_place_type_constraints_on_same_line = false +resharper_csharp_prefer_qualified_reference = false +resharper_csharp_use_indent_from_vs = false +resharper_csharp_wrap_arguments_style = chop_always +resharper_csharp_wrap_chained_method_calls = chop_always +resharper_csharp_wrap_for_stmt_header_style = wrap_if_long +resharper_csharp_wrap_multiple_declaration_style = chop_always +resharper_csharp_wrap_multiple_type_parameter_constraints_style = chop_always +resharper_csharp_wrap_parameters_style = chop_always +resharper_csharp_wrap_ternary_expr_style = chop_always +resharper_indent_anonymous_method_block = true +resharper_indent_text = OneIndent +resharper_int_align = true +resharper_keep_existing_arrangement = false +resharper_local_function_body = expression_body +resharper_max_enum_members_on_line = 1 +resharper_nested_ternary_style = expanded +resharper_place_attribute_on_same_line = false +resharper_place_constructor_initializer_on_same_line = false +resharper_place_expr_method_on_single_line = false +resharper_place_expr_property_on_single_line = false +resharper_place_linq_into_on_new_line = false +resharper_place_simple_anonymousmethod_on_single_line = false +resharper_place_simple_embedded_statement_on_same_line = false +resharper_place_simple_initializer_on_single_line = false +resharper_place_simple_property_pattern_on_single_line = false +resharper_enforce_line_ending_style = true +resharper_protobuf_indent_size = 2 +resharper_protobuf_tab_width = 2 +resharper_protobuf_use_indent_from_vs = false +resharper_trailing_comma_in_multiline_lists = true +resharper_wrap_after_primary_constructor_declaration_lpar = false +resharper_wrap_array_initializer_style = chop_always +resharper_wrap_before_arrow_with_expressions = true +resharper_wrap_before_binary_pattern_op = false +resharper_wrap_before_linq_expression = true +resharper_wrap_linq_expressions = chop_always +resharper_wrap_object_and_collection_initializer_style = chop_always +resharper_wrap_primary_constructor_parameters_style = chop_always +resharper_wrap_property_pattern = chop_always +resharper_xmldoc_indent_text = OneIndent +resharper_xml_indent_size = 2 +resharper_xml_tab_width = 2 +resharper_xml_use_indent_from_vs = false + +# ReSharper inspection severities +resharper_arrange_redundant_parentheses_highlighting = hint +resharper_arrange_this_qualifier_highlighting = hint +resharper_arrange_type_member_modifiers_highlighting = hint +resharper_arrange_type_modifiers_highlighting = hint +resharper_built_in_type_reference_style_for_member_access_highlighting = hint +resharper_built_in_type_reference_style_highlighting = hint +resharper_enforce_foreach_statement_braces_highlighting = warning +resharper_enforce_for_statement_braces_highlighting = warning +resharper_enforce_if_statement_braces_highlighting = warning +resharper_enforce_while_statement_braces_highlighting = warning +resharper_redundant_base_qualifier_highlighting = warning +resharper_suggest_var_or_type_built_in_types_highlighting = hint +resharper_suggest_var_or_type_elsewhere_highlighting = hint +resharper_suggest_var_or_type_simple_types_highlighting = hintroot = true \ No newline at end of file diff --git a/.github/workflows/code-formatting.yml b/.github/workflows/code-formatting.yml new file mode 100644 index 0000000..0cdeb35 --- /dev/null +++ b/.github/workflows/code-formatting.yml @@ -0,0 +1,57 @@ +name: Code Formatting + +on: + pull_request: + workflow_dispatch: + +jobs: + format-csharp: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + with: + ref: ${{ github.ref }} + + - name: Install .NET Core + uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4 + with: + dotnet-version: 8.x + + - name: Install ReSharper + run: | + dotnet tool install -g JetBrains.ReSharper.GlobalTools --version 2022.3.3 + + - name: Restore + run: | + dotnet restore ArmoniK.TaskReRunner.sln + - name: Reformat + run: | + jb cleanupcode --profile="Full Cleanup With Headers" ArmoniK.TaskReRunner.sln + + - name: Check Diff + id: check-diff + run: | + DIFF="$(git diff --name-only)" + + if [ -z "$DIFF" ]; then + echo "OK: Format is clean" + else + echo "Error: Format was not clean" + echo "List of files:" + echo "$DIFF" + git diff + exit 1 + fi + + - name: Generate patch + if: ${{ failure() && steps.check-diff.conclusion == 'failure' }} + run: | + git diff > patch-csharp.diff + + - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4 + if: ${{ failure() && steps.check-diff.conclusion == 'failure' }} + with: + name: patch-csharp + path: ./patch-csharp.diff \ No newline at end of file diff --git a/ArmoniK.TaskReRunner.sln b/ArmoniK.TaskReRunner.sln index 069e32a..b9a9321 100644 --- a/ArmoniK.TaskReRunner.sln +++ b/ArmoniK.TaskReRunner.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.10.34916.146 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArmoniK.TaskReRunner", "ArmoniK.TaskReRunner.csproj", "{4734A3B6-02C9-4F53-8127-A97F2F6D4DDD}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArmoniK.TaskReRunner", "./src/TaskReRunner/ArmoniK.TaskReRunner.csproj", "{4734A3B6-02C9-4F53-8127-A97F2F6D4DDD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/ArmoniK.TaskReRunner.sln.DotSettings b/ArmoniK.TaskReRunner.sln.DotSettings new file mode 100644 index 0000000..0483531 --- /dev/null +++ b/ArmoniK.TaskReRunner.sln.DotSettings @@ -0,0 +1,38 @@ +<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> + <s:String x:Key="/Default/CodeEditing/TypingAssist/FormatOnPaste/@EntryValue">FullFormat</s:String> + <s:Boolean x:Key="/Default/CodeStyle/CodeCleanup/CleanupOnSave/@EntryValue">True</s:Boolean> + <s:String x:Key="/Default/CodeStyle/CodeCleanup/CleanupOnSaveFileMask/@EntryValue">*.{cs,cpp,c,hpp,h,csproj,xml}</s:String> + <s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Full/@EntryIndexedValue"></s:String> + <s:Boolean x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Full/@EntryIndexRemoved">True</s:Boolean> + <s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Full_0020Cleanup_0020With_0020Headers/@EntryIndexedValue"><?xml version="1.0" encoding="utf-16"?><Profile name="Full Cleanup With Headers"><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><CppAddTypenameTemplateKeywords>True</CppAddTypenameTemplateKeywords><CppRemoveCastDescriptor>True</CppRemoveCastDescriptor><CppRemoveElseKeyword>True</CppRemoveElseKeyword><CppShortenQualifiedName>True</CppShortenQualifiedName><CppDeleteRedundantSpecifier>True</CppDeleteRedundantSpecifier><CppRemoveStatement>True</CppRemoveStatement><CppDeleteRedundantTypenameTemplateKeywords>True</CppDeleteRedundantTypenameTemplateKeywords><CppCStyleToStaticCastDescriptor>True</CppCStyleToStaticCastDescriptor><CppReplaceExpressionWithBooleanConst>True</CppReplaceExpressionWithBooleanConst><CppMakeIfConstexpr>True</CppMakeIfConstexpr><CppMakePostfixOperatorPrefix>True</CppMakePostfixOperatorPrefix><CppChangeSmartPointerToMakeFunction>True</CppChangeSmartPointerToMakeFunction><CppReplaceThrowWithRethrowFix>True</CppReplaceThrowWithRethrowFix><CppTypeTraitAliasDescriptor>True</CppTypeTraitAliasDescriptor><CppReplaceExpressionWithNullptr>True</CppReplaceExpressionWithNullptr><CppReplaceTieWithStructuredBindingDescriptor>True</CppReplaceTieWithStructuredBindingDescriptor><CppUseAssociativeContainsDescriptor>True</CppUseAssociativeContainsDescriptor><CppUseEraseAlgorithmDescriptor>True</CppUseEraseAlgorithmDescriptor><CppCodeStyleCleanupDescriptor ArrangeBraces="True" ArrangeAuto="True" ArrangeFunctionDeclarations="True" ArrangeNestedNamespaces="True" ArrangeTypeAliases="True" ArrangeCVQualifiers="True" ArrangeSlashesInIncludeDirectives="True" ArrangeOverridingFunctions="True" SortIncludeDirectives="True" SortMemberInitializers="True" /><CppReformatCode>True</CppReformatCode><CppUpdateFileHeader>True</CppUpdateFileHeader><CSReorderTypeMembers>True</CSReorderTypeMembers><CSCodeStyleAttributes ArrangeVarStyle="True" ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" ArrangeArgumentsStyle="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeCodeBodyStyle="True" ArrangeTrailingCommas="True" ArrangeObjectCreation="True" ArrangeDefaultValue="True" ArrangeNamespaces="True" /><CSUpdateFileHeader>True</CSUpdateFileHeader><CssAlphabetizeProperties>True</CssAlphabetizeProperties><JSStringLiteralQuotesDescriptor>True</JSStringLiteralQuotesDescriptor><CorrectVariableKindsDescriptor>True</CorrectVariableKindsDescriptor><VariablesToInnerScopesDescriptor>True</VariablesToInnerScopesDescriptor><StringToTemplatesDescriptor>True</StringToTemplatesDescriptor><JsInsertSemicolon>True</JsInsertSemicolon><RemoveRedundantQualifiersTs>True</RemoveRedundantQualifiersTs><OptimizeImportsTs>True</OptimizeImportsTs><OptimizeReferenceCommentsTs>True</OptimizeReferenceCommentsTs><PublicModifierStyleTs>True</PublicModifierStyleTs><ExplicitAnyTs>True</ExplicitAnyTs><TypeAnnotationStyleTs>True</TypeAnnotationStyleTs><RelativePathStyleTs>True</RelativePathStyleTs><AsInsteadOfCastTs>True</AsInsteadOfCastTs><RemoveCodeRedundanciesVB>True</RemoveCodeRedundanciesVB><Xaml.RedundantFreezeAttribute>True</Xaml.RedundantFreezeAttribute><Xaml.RemoveRedundantModifiersAttribute>True</Xaml.RemoveRedundantModifiersAttribute><Xaml.RemoveRedundantNameAttribute>True</Xaml.RemoveRedundantNameAttribute><Xaml.RemoveRedundantResource>True</Xaml.RemoveRedundantResource><Xaml.RemoveRedundantCollectionProperty>True</Xaml.RemoveRedundantCollectionProperty><Xaml.RemoveRedundantAttachedPropertySetter>True</Xaml.RemoveRedundantAttachedPropertySetter><Xaml.RemoveRedundantStyledValue>True</Xaml.RemoveRedundantStyledValue><Xaml.RemoveRedundantNamespaceAlias>True</Xaml.RemoveRedundantNamespaceAlias><Xaml.RemoveForbiddenResourceName>True</Xaml.RemoveForbiddenResourceName><Xaml.RemoveRedundantGridDefinitionsAttribute>True</Xaml.RemoveRedundantGridDefinitionsAttribute><Xaml.RemoveRedundantUpdateSourceTriggerAttribute>True</Xaml.RemoveRedundantUpdateSourceTriggerAttribute><Xaml.RemoveRedundantBindingModeAttribute>True</Xaml.RemoveRedundantBindingModeAttribute><Xaml.RemoveRedundantGridSpanAttribut>True</Xaml.RemoveRedundantGridSpanAttribut><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><CssReformatCode>True</CssReformatCode><HtmlReformatCode>True</HtmlReformatCode><JsReformatCode>True</JsReformatCode><JsFormatDocComments>True</JsFormatDocComments><VBOptimizeImports>True</VBOptimizeImports><VBShortenReferences>True</VBShortenReferences><XMLReformatCode>True</XMLReformatCode><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><VBReformatCode>True</VBReformatCode><VBFormatDocComments>True</VBFormatDocComments><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor></Profile></s:String> + <s:Boolean x:Key="/Default/CodeStyle/CodeCleanup/SaveAfterCleanup/@EntryValue">True</s:Boolean> + <s:String x:Key="/Default/CodeStyle/CodeCleanup/SilentCleanupProfile/@EntryValue">Full Cleanup With Headers</s:String> + <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=Affero/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=Amqp/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=ANEO/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=appsettings/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=Armoni/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=Armonik/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=Djebbar/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=Dubuc/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=gridlib/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=Grpc/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=Gurhem/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=Initializable/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=Khodja/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=Kirschenmann/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=Liveness/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=Mongo/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=prefetching/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=qmdm/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=redispatched/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=requeued/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=serilog/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=subtask/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=subtasking/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=subtasks/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/UserDictionary/Words/=Ziane/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> \ No newline at end of file diff --git a/src/TaskReRunner/Agent.cs b/src/TaskReRunner/Agent.cs new file mode 100644 index 0000000..c5ea35d --- /dev/null +++ b/src/TaskReRunner/Agent.cs @@ -0,0 +1,211 @@ +// This file is part of the ArmoniK project +// +// Copyright (C) ANEO, 2021-2024. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License") +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +using ArmoniK.Api.gRPC.V1; +using ArmoniK.Api.gRPC.V1.Agent; +using ArmoniK.TaskReRunner.Utils; + +using Google.Protobuf.WellKnownTypes; + +using Grpc.Core; + +namespace ArmoniK.TaskReRunner; + +/// <summary> +/// A storage class to keep Tasks and Result data. +/// </summary> +internal class AgentStorage +{ + public readonly HashSet<string> _notifiedResults = new(); + public ConcurrentDictionary<string, Result> _Results = new(); + public ConcurrentDictionary<string, TaskData> _Tasks = new(); +} + +internal class ReRunnerAgent : Agent.AgentBase +{ + private readonly AgentStorage storage_; + + /// <summary> + /// Initializes a new instance of the RerunAgent class with the specified storage. + /// </summary> + /// <param name="storage">An instance of AgentStorage used to store agent data.</param> + public ReRunnerAgent(AgentStorage storage) + => storage_ = storage; + + /// <summary> + /// Creates a Result with its MetaData: generates a result ID, retrieves its name, sets its status to created, adds the + /// creation date, and retrieves the session ID. + /// Registers the created result and its data in Results. + /// </summary> + /// <param name="request">Data related to the CreateResults request</param> + /// <param name="context">Data related to the server</param> + /// <returns>A response containing the created Result</returns> + public override Task<CreateResultsResponse> CreateResults(CreateResultsRequest request, + ServerCallContext context) + { + var results = request.Results.Select(rc => + { + var resultId = Guid.NewGuid() + .ToString(); + var current = new Result + { + ResultId = resultId, + Name = rc.Name, + Status = ResultStatus.Created, + CreatedAt = DateTime.UtcNow, + SessionId = request.SessionId, + Data = rc.Data.ToByteArray(), + }; + storage_._Results[resultId] = current; + return current; + }); + + return Task.FromResult(new CreateResultsResponse + { + CommunicationToken = request.CommunicationToken, + Results = + { + results.Select(result => new ResultMetaData + { + CreatedAt = Timestamp.FromDateTime(result.CreatedAt), + Name = result.Name, + SessionId = result.SessionId, + Status = result.Status ?? ResultStatus.Unspecified, + ResultId = result.ResultId, + }), + }, + }); + } + + /// <summary> + /// Creates Result MetaData: generates a result ID, retrieves its name, sets its status to created, adds the creation + /// date, and retrieves the session ID. + /// Registers the created result metadata without any data in Results. + /// </summary> + /// <param name="request">Data related to CreateResultsMetaData the request</param> + /// <param name="context">Data related to the server</param> + /// <returns>A response containing the created Result MetaData</returns> + public override Task<CreateResultsMetaDataResponse> CreateResultsMetaData(CreateResultsMetaDataRequest request, + ServerCallContext context) + { + var results = request.Results.Select(rc => + { + var resultId = Guid.NewGuid() + .ToString(); + + return new Result + { + ResultId = resultId, + Name = rc.Name, + Status = ResultStatus.Created, + CreatedAt = DateTime.UtcNow, + SessionId = request.SessionId, + Data = null, + }; + }); + + return Task.FromResult(new CreateResultsMetaDataResponse + { + CommunicationToken = request.CommunicationToken, + Results = + { + results.Select(result => new ResultMetaData + { + CreatedAt = Timestamp.FromDateTime(result.CreatedAt), + Name = result.Name, + SessionId = result.SessionId, + Status = result.Status ?? ResultStatus.Unspecified, + ResultId = result.ResultId, + }), + }, + }); + } + + /// <summary> + /// Notifies result data: adds result IDs from the request to the notified results list in storage. + /// </summary> + /// <param name="request">Data related to the NotifyResultData request</param> + /// <param name="context">Data related to the server</param> + /// <returns>A response containing the notified result IDs</returns> + public override Task<NotifyResultDataResponse> NotifyResultData(NotifyResultDataRequest request, + ServerCallContext context) + { + foreach (var result in request.Ids) + { + storage_._notifiedResults.Add(result.ResultId); + } + + return Task.FromResult(new NotifyResultDataResponse + { + ResultIds = + { + request.Ids.Select(identifier => identifier.ResultId), + }, + }); + } + + /// <summary> + /// Submits tasks: generates task IDs, retrieves their data dependencies, expected output keys, and payload IDs. + /// Registers the created tasks in Tasks. + /// </summary> + /// <param name="request">Data related to the SubmitTasks request</param> + /// <param name="context">Data related to the server</param> + /// <returns>A response containing information about the submitted tasks</returns> + public override Task<SubmitTasksResponse> SubmitTasks(SubmitTasksRequest request, + ServerCallContext context) + { + var createdTasks = request.TaskCreations.Select(rc => + { + var taskId = Guid.NewGuid() + .ToString(); + var current = new TaskData + { + DataDependencies = rc.DataDependencies, + ExpectedOutputKeys = rc.ExpectedOutputKeys, + PayloadId = rc.PayloadId, + TaskId = taskId, + }; + storage_._Tasks[taskId] = current; + return current; + }); + return Task.FromResult(new SubmitTasksResponse + { + CommunicationToken = request.CommunicationToken, + TaskInfos = + { + createdTasks.Select(creationRequest => new SubmitTasksResponse.Types.TaskInfo + { + DataDependencies = + { + creationRequest.DataDependencies, + }, + ExpectedOutputIds = + { + creationRequest.ExpectedOutputKeys, + }, + PayloadId = creationRequest.PayloadId, + TaskId = creationRequest.TaskId, + }), + }, + }); + } +} diff --git a/src/TaskReRunner/MyAgent.cs b/src/TaskReRunner/MyAgent.cs deleted file mode 100644 index 635729b..0000000 --- a/src/TaskReRunner/MyAgent.cs +++ /dev/null @@ -1,206 +0,0 @@ -using ArmoniK.Api.gRPC.V1.Agent; -using ArmoniK.Api.gRPC.V1; -using System.Threading.Tasks; -using Google.Protobuf.WellKnownTypes; -using Grpc.Core; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using ArmoniK.TaskReRunner.Utils; - -namespace ArmoniK.TaskReRunner.MyAgent -{ - /// <summary> - /// A storage class to keep Tasks and Result data. - /// </summary> - internal class AgentStorage - { - public readonly HashSet<string> _notifiedResults = new(); - public ConcurrentDictionary<string, Result> _Results = new(); - public ConcurrentDictionary<string, TaskData> _Tasks = new(); - } - - internal class RerunAgent : Agent.AgentBase - { - private readonly AgentStorage _storage; - - /// <summary> - /// Initializes a new instance of the RerunAgent class with the specified storage. - /// </summary> - /// <param name="storage">An instance of AgentStorage used to store agent data.</param> - public RerunAgent(AgentStorage storage) - { - _storage = storage; - } - - /// <summary> - /// Creates a Result with its MetaData: generates a result ID, retrieves its name, sets its status to created, adds the creation date, and retrieves the session ID. - /// Registers the created result and its data in Results. - /// </summary> - /// <param name="request">Data related to the CreateResults request</param> - /// <param name="context">Data related to the server</param> - /// <returns>A response containing the created Result</returns> - public override Task<CreateResultsResponse> CreateResults(CreateResultsRequest request, - ServerCallContext context) - { - Console.ForegroundColor = ConsoleColor.Blue; - Console.WriteLine("[INFO] Entered in CreateResults"); - Console.ResetColor(); - - var results = request.Results.Select(rc => - { - var resultId = Guid.NewGuid().ToString(); - var current = new Result - { - ResultId = resultId, - Name = rc.Name, - Status = ResultStatus.Created, - CreatedAt = DateTime.UtcNow, - SessionId = request.SessionId, - Data = rc.Data.ToByteArray(), - }; - _storage._Results[resultId] = current; - return current; - }); - - return Task.FromResult(new CreateResultsResponse - { - CommunicationToken = request.CommunicationToken, - Results = - { - results.Select(result => new ResultMetaData - { - CreatedAt = Timestamp.FromDateTime(result.CreatedAt), - Name = result.Name, - SessionId = result.SessionId, - Status = result.Status, - ResultId = result.ResultId, - }) - } - }); - } - - /// <summary> - /// Creates Result MetaData: generates a result ID, retrieves its name, sets its status to created, adds the creation date, and retrieves the session ID. - /// Registers the created result metadata without any data in Results. - /// </summary> - /// <param name="request">Data related to CreateResultsMetaData the request</param> - /// <param name="context">Data related to the server</param> - /// <returns>A response containing the created Result MetaData</returns> - public override Task<CreateResultsMetaDataResponse> CreateResultsMetaData(CreateResultsMetaDataRequest request, - ServerCallContext context) - { - Console.ForegroundColor = ConsoleColor.Blue; - Console.WriteLine("[INFO] Entered in CreateResultsMetaData"); - Console.ResetColor(); - - - var results = request.Results.Select(rc => - { - var resultId = Guid.NewGuid().ToString(); - - return new Result - { - ResultId = resultId, - Name = rc.Name, - Status = ResultStatus.Created, - CreatedAt = DateTime.UtcNow, - SessionId = request.SessionId, - Data = null, - }; - }); - - return Task.FromResult(new CreateResultsMetaDataResponse - { - CommunicationToken = request.CommunicationToken, - Results = - { - results.Select(result => new ResultMetaData - { - CreatedAt = Timestamp.FromDateTime(result.CreatedAt), - Name = result.Name, - SessionId = result.SessionId, - Status = result.Status, - ResultId = result.ResultId, - }) - } - }); - } - - /// <summary> - /// Notifies result data: adds result IDs from the request to the notified results list in storage. - /// </summary> - /// <param name="request">Data related to the NotifyResultData request</param> - /// <param name="context">Data related to the server</param> - /// <returns>A response containing the notified result IDs</returns> - public override Task<NotifyResultDataResponse> NotifyResultData(NotifyResultDataRequest request, - ServerCallContext context) - { - Console.ForegroundColor = ConsoleColor.Blue; - Console.WriteLine("[INFO] Entered in NotifyResultData"); - Console.ResetColor(); - foreach (var result in request.Ids) - { - _storage._notifiedResults.Add(result.ResultId); - } - - return Task.FromResult(new NotifyResultDataResponse - { - ResultIds = - { - request.Ids.Select(identifier => identifier.ResultId) - } - }); - } - - /// <summary> - /// Submits tasks: generates task IDs, retrieves their data dependencies, expected output keys, and payload IDs. - /// Registers the created tasks in Tasks. - /// </summary> - /// <param name="request">Data related to the SubmitTasks request</param> - /// <param name="context">Data related to the server</param> - /// <returns>A response containing information about the submitted tasks</returns> - public override Task<SubmitTasksResponse> SubmitTasks(SubmitTasksRequest request, ServerCallContext context) - { - Console.ForegroundColor = ConsoleColor.Blue; - Console.WriteLine("[INFO] Entered in SubmitTasks"); - Console.ResetColor(); - - var createdTasks = request.TaskCreations.Select(rc => - { - var taskId = Guid.NewGuid().ToString(); - var current = new TaskData - { - DataDependencies = rc.DataDependencies, - ExpectedOutputKeys = rc.ExpectedOutputKeys, - PayloadId = rc.PayloadId, - TaskId = taskId, - }; - _storage._Tasks[taskId] = current; - return current; - }); - return Task.FromResult(new SubmitTasksResponse - { - CommunicationToken = request.CommunicationToken, - TaskInfos = - { - createdTasks.Select(creationRequest => new SubmitTasksResponse.Types.TaskInfo - { - DataDependencies = - { - creationRequest.DataDependencies, - }, - ExpectedOutputIds = - { - creationRequest.ExpectedOutputKeys, - }, - PayloadId = creationRequest.PayloadId, - TaskId = creationRequest.TaskId, - }), - }, - }); - } - } -} \ No newline at end of file diff --git a/src/TaskReRunner/Program.cs b/src/TaskReRunner/Program.cs index d51450e..3d6b9b6 100644 --- a/src/TaskReRunner/Program.cs +++ b/src/TaskReRunner/Program.cs @@ -1,177 +1,208 @@ -using System; -using System.Collections.Concurrent; -using ArmoniK.TaskReRunner.MyAgent; -using ArmoniK.Api.Common.Channel.Utils; -using Microsoft.Extensions.Logging.Abstractions; -using GrpcChannel = ArmoniK.Api.Common.Options.GrpcChannel; -using ArmoniK.Api.gRPC.V1.Worker; -using ArmoniK.Api.gRPC.V1; -using Microsoft.AspNetCore.Routing; -using Microsoft.Extensions.Logging; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Threading; -using ArmoniK.Api.gRPC.V1.Agent; -using ArmoniK.TaskReRunner.Utils; -using Google.Protobuf.Collections; -using Grpc.Core; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Server.Kestrel.Core; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging.Configuration; -using Google.Protobuf.WellKnownTypes; -using Grpc.AspNetCore.Server; -using Serilog; -using Serilog.Core; -using Serilog.Formatting.Compact; -using ArmoniK.TaskReRunner.Server; - - -internal static class Program -{ - /// <summary> - /// Connect to a Worker to process tasks with specific process parameter. - /// </summary> - /// <param name="arg">Command-line arguments.</param> - public static void Main(string[] arg) - { - // Create a logger configuration to write output to the console with contextual information. - var loggerConfiguration_ = new LoggerConfiguration() - .WriteTo.Console() - .Enrich.FromLogContext() - .CreateLogger(); - - // Create a logger using the configured logger settings - var logger_ = LoggerFactory.Create(builder => builder.AddSerilog(loggerConfiguration_)) - .CreateLogger("root"); - - // Set up the gRPC channel with the specified address and a null logger for the provider - var channel = new GrpcChannelProvider(new GrpcChannel { Address = "/tmp/worker.sock" }, - new NullLogger<GrpcChannelProvider>()).Get(); - - // Create a gRPC client for the Worker service - var client = new Worker.WorkerClient(channel); - - // Generate a unique identifier for the payload - var payloadId = Guid.NewGuid().ToString(); - - // Generate a unique identifier for the task - var taskId = Guid.NewGuid().ToString(); - - // Generate a unique identifier for the communication token - var token = Guid.NewGuid().ToString(); - - // Generate a unique identifier for the session - var sessionId = Guid.NewGuid().ToString(); - - // Generate a unique identifier for the first data dependency - var dd1 = Guid.NewGuid().ToString(); - - // Generate a unique identifier for the first expected output key - var eok1 = Guid.NewGuid().ToString(); - - // Generate a unique identifier for the second expected output key - var eok2 = Guid.NewGuid().ToString(); - - // Create a temporary directory and get its full path - var folder = Directory.CreateTempSubdirectory().FullName; - - // Convert the integer 8 to a byte array for the payload - var payloadBytes = BitConverter.GetBytes(8); - - // Convert the string "DataDependency1" to a byte array using ASCII encoding - var dd1Bytes = Encoding.ASCII.GetBytes("DataDependency1"); - - // Write payloadBytes in the corresponding file - File.WriteAllBytesAsync(Path.Combine(folder, - payloadId), - payloadBytes); - - // Write payloadBytes in the corresponding file - File.WriteAllBytesAsync(Path.Combine(folder, - dd1), - dd1Bytes); - // Create an AgentStorage to keep the Agent Data After Process - var storage = new AgentStorage(); - - - // Scope for the Task to run - { - using var server = new Server("/tmp/agent.sock", storage, loggerConfiguration_); - - // To test subtasking partition - var taskOptions = new TaskOptions(); - taskOptions.Options["UseCase"] = "Launch"; - var configuration = new Configuration - { - DataChunkMaxSize = 84, - }; - - // Register the parameters needed for processing : - // communication token, payload and session IDs, configuration settings, data dependencies, folder location, expected output keys, task ID, and task options. - var toProcess = new ProcessData - { - CommunicationToken = token, - PayloadId = payloadId, - SessionId = sessionId, - Configuration = configuration, - DataDependencies = new RepeatedField<string> { dd1 }, - DataFolder = folder, - ExpectedOutputKeys = new RepeatedField<string> { eok1 }, - TaskId = taskId, - TaskOptions = taskOptions - }; - - // Call the Process method on the gRPC client `client` of type Worker.WorkerClient - client.Process(new ProcessRequest - { - CommunicationToken = token, - PayloadId = payloadId, - SessionId = sessionId, - Configuration = configuration, - DataDependencies = - { - dd1, - }, - DataFolder = folder, - ExpectedOutputKeys = - { - eok1, - //eok2, // Uncomment to test multiple expected output keys (results) - }, - TaskId = taskId, - TaskOptions = taskOptions - }); - - logger_.LogInformation("First Task Data: {toProcess}", toProcess); - } - - // print everything in agent storage - - logger_.LogInformation("resultsIds : {results}", storage._notifiedResults); - - var i = 0; - foreach (var result in storage._notifiedResults) - { - var str = File.ReadAllBytes(Path.Combine(folder, - result)); - logger_.LogInformation("Notified result Data : {str}", str); - logger_.LogInformation("Notified result Id{i}: {res}", i, result); - i++; - } - - logger_.LogInformation("results : {results}", storage._Results); - foreach (var result in storage._Results) - { - var str = result.Value.Data; - logger_.LogInformation("Create Result Data : {str}", str); - } - - logger_.LogInformation("Submitted Tasks Data : {results}", storage._Tasks); - } -} \ No newline at end of file +// This file is part of the ArmoniK project +// +// Copyright (C) ANEO, 2021-2024. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License") +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using System.IO; +using System.Text; + +using ArmoniK.Api.Common.Channel.Utils; +using ArmoniK.Api.Common.Options; +using ArmoniK.Api.gRPC.V1; +using ArmoniK.Api.gRPC.V1.Worker; +using ArmoniK.TaskReRunner; +using ArmoniK.TaskReRunner.Utils; + +using Google.Protobuf.Collections; + +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; + +using Serilog; + +internal static class Program +{ + /// <summary> + /// Connect to a Worker to process tasks with specific process parameter. + /// </summary> + /// <param name="arg">Command-line arguments.</param> + public static void Main(string[] arg) + { + // Create a logger configuration to write output to the console with contextual information. + var loggerConfiguration_ = new LoggerConfiguration().WriteTo.Console() + .Enrich.FromLogContext() + .CreateLogger(); + + // Create a logger using the configured logger settings + var logger_ = LoggerFactory.Create(builder => builder.AddSerilog(loggerConfiguration_)) + .CreateLogger("root"); + + // Set up the gRPC channel with the specified address and a null logger for the provider + var channel = new GrpcChannelProvider(new GrpcChannel + { + Address = "/tmp/worker.sock", + }, + new NullLogger<GrpcChannelProvider>()).Get(); + + // Create a gRPC client for the Worker service + var client = new Worker.WorkerClient(channel); + + // Generate a unique identifier for the payload + var payloadId = Guid.NewGuid() + .ToString(); + + // Generate a unique identifier for the task + var taskId = Guid.NewGuid() + .ToString(); + + // Generate a unique identifier for the communication token + var token = Guid.NewGuid() + .ToString(); + + // Generate a unique identifier for the session + var sessionId = Guid.NewGuid() + .ToString(); + + // Generate a unique identifier for the first data dependency + var dd1 = Guid.NewGuid() + .ToString(); + + // Generate a unique identifier for the first expected output key + var eok1 = Guid.NewGuid() + .ToString(); + + // Generate a unique identifier for the second expected output key + var eok2 = Guid.NewGuid() + .ToString(); + + // Create a temporary directory and get its full path + var folder = Directory.CreateTempSubdirectory() + .FullName; + + // Convert the integer 8 to a byte array for the payload + var payloadBytes = BitConverter.GetBytes(8); + + // Convert the string "DataDependency1" to a byte array using ASCII encoding + var dd1Bytes = Encoding.ASCII.GetBytes("DataDependency1"); + + // Write payloadBytes in the corresponding file + File.WriteAllBytesAsync(Path.Combine(folder, + payloadId), + payloadBytes); + + // Write payloadBytes in the corresponding file + File.WriteAllBytesAsync(Path.Combine(folder, + dd1), + dd1Bytes); + // Create an AgentStorage to keep the Agent Data After Process + var storage = new AgentStorage(); + + + // Scope for the Task to run + { + // Launch a Agent server to listen the worker + using var server = new Server("/tmp/agent.sock", + storage, + loggerConfiguration_); + + // To test subtasking partition + var taskOptions = new TaskOptions(); + taskOptions.Options["UseCase"] = "Launch"; + var configuration = new Configuration + { + DataChunkMaxSize = 84, + }; + + // Register the parameters needed for processing : + // communication token, payload and session IDs, configuration settings, data dependencies, folder location, expected output keys, task ID, and task options. + var toProcess = new ProcessData + { + CommunicationToken = token, + PayloadId = payloadId, + SessionId = sessionId, + Configuration = configuration, + DataDependencies = new RepeatedField<string> + { + dd1, + }, + DataFolder = folder, + ExpectedOutputKeys = new RepeatedField<string> + { + eok1, + }, + TaskId = taskId, + TaskOptions = taskOptions, + }; + + // Call the Process method on the gRPC client `client` of type Worker.WorkerClient + client.Process(new ProcessRequest + { + CommunicationToken = token, + PayloadId = payloadId, + SessionId = sessionId, + Configuration = configuration, + DataDependencies = + { + dd1, + }, + DataFolder = folder, + ExpectedOutputKeys = + { + eok1, + //eok2, // Uncomment to test multiple expected output keys (results) + }, + TaskId = taskId, + TaskOptions = taskOptions, + }); + + logger_.LogInformation("First Task Data: {toProcess}", + toProcess); + } + + // print everything in agent storage + + logger_.LogInformation("resultsIds : {results}", + storage._notifiedResults); + + var i = 0; + foreach (var result in storage._notifiedResults) + { + var byteArray = File.ReadAllBytes(Path.Combine(folder, + result)); + logger_.LogInformation("Notified result Data : {str}", + byteArray); + logger_.LogInformation("Notified result Id{i}: {res}", + i, + result); + i++; + } + + logger_.LogInformation("results : {results}", + storage._Results); + foreach (var result in storage._Results) + { + var str = result.Value.Data; + logger_.LogInformation("Create Result Data : {str}", + str); + } + + logger_.LogInformation("Submitted Tasks Data : {results}", + storage._Tasks); + + File.WriteAllBytesAsync(Path.Combine(folder, + dd1), + dd1Bytes); + } +} diff --git a/src/TaskReRunner/Server.cs b/src/TaskReRunner/Server.cs index b36b41c..8b26a31 100644 --- a/src/TaskReRunner/Server.cs +++ b/src/TaskReRunner/Server.cs @@ -1,70 +1,91 @@ -using System; -using System.IO; -using ArmoniK.TaskReRunner.MyAgent; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Server.Kestrel.Core; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Serilog; -using Serilog.Core; - -namespace ArmoniK.TaskReRunner.Server -{ - internal class Server : IDisposable - { - private readonly System.Threading.Tasks.Task _runningApp; - private readonly WebApplication _app; - - - /// <summary> - /// Initializes a new instance of the Server class, configuring the server to listen on a Unix socket, set up logging, and add gRPC services. - /// </summary> - /// <param name="socket">The Unix socket path for the server to listen on.</param> - /// <param name="storage">The AgentStorage instance to store agent data.</param> - /// <param name="loggerConfiguration">The Serilog logger configuration for logging.</param> - public Server(string socket, AgentStorage storage, Logger loggerConfiguration) - { - var builder = WebApplication.CreateBuilder(); - - builder.WebHost.ConfigureKestrel(options => options.ListenUnixSocket(socket, - listenOptions => - { - if (File.Exists(socket)) - { - File.Delete(socket); - } - - listenOptions.Protocols = HttpProtocols.Http2; - })); - - builder.Host.UseSerilog(loggerConfiguration); - - builder.Services - .AddSingleton(storage) - .AddGrpcReflection() - .AddGrpc(options => options.MaxReceiveMessageSize = null); - - _app = builder.Build(); - - if (_app.Environment.IsDevelopment()) - { - _app.UseDeveloperExceptionPage(); - _app.MapGrpcReflectionService(); - } - - _app.UseRouting(); - _app.MapGrpcService<RerunAgent>(); - _runningApp = _app.RunAsync(); - } - - /// <summary> - /// Disposes resources used by the application, stopping the application and waiting for it to finish. - /// </summary> - public void Dispose() - { - _app.StopAsync().Wait(); - _runningApp.Wait(); - } - } -} \ No newline at end of file +// This file is part of the ArmoniK project +// +// Copyright (C) ANEO, 2021-2024. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License") +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using System.IO; +using System.Threading.Tasks; + +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Server.Kestrel.Core; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +using Serilog; +using Serilog.Core; + +namespace ArmoniK.TaskReRunner; + +internal class Server : IDisposable +{ + private readonly WebApplication app_; + private readonly Task runningApp_; + + + /// <summary> + /// Initializes a new instance of the Server class, configuring the server to listen on a Unix socket, set up logging, + /// and add gRPC services. + /// </summary> + /// <param name="socket">The Unix socket path for the server to listen on.</param> + /// <param name="storage">The AgentStorage instance to store agent data.</param> + /// <param name="loggerConfiguration">The Serilog logger configuration for logging.</param> + public Server(string socket, + AgentStorage storage, + Logger loggerConfiguration) + { + var builder = WebApplication.CreateBuilder(); + + builder.WebHost.ConfigureKestrel(options => options.ListenUnixSocket(socket, + listenOptions => + { + if (File.Exists(socket)) + { + File.Delete(socket); + } + + listenOptions.Protocols = HttpProtocols.Http2; + })); + + builder.Host.UseSerilog(loggerConfiguration); + + builder.Services.AddSingleton(storage) + .AddGrpcReflection() + .AddGrpc(options => options.MaxReceiveMessageSize = null); + + app_ = builder.Build(); + + if (app_.Environment.IsDevelopment()) + { + app_.UseDeveloperExceptionPage(); + app_.MapGrpcReflectionService(); + } + + app_.UseRouting(); + app_.MapGrpcService<ReRunnerAgent>(); + runningApp_ = app_.RunAsync(); + } + + /// <summary> + /// Disposes resources used by the application, stopping the application and waiting for it to finish. + /// </summary> + public void Dispose() + { + app_.StopAsync() + .Wait(); + runningApp_.Wait(); + app_.DisposeAsync(); + } +} diff --git a/src/TaskReRunner/Utils.cs b/src/TaskReRunner/Utils.cs index ac5e1e9..4116493 100644 --- a/src/TaskReRunner/Utils.cs +++ b/src/TaskReRunner/Utils.cs @@ -1,50 +1,63 @@ -using ArmoniK.Api.gRPC.V1; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +// This file is part of the ArmoniK project +// +// Copyright (C) ANEO, 2021-2024. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License") +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using System.Collections.Generic; + +using ArmoniK.Api.gRPC.V1; + +namespace ArmoniK.TaskReRunner.Utils; -namespace ArmoniK.TaskReRunner.Utils +/// <summary> +/// Represents all the parameters needed to launch a process : communication token, payload and session IDs, +/// configuration settings, data dependencies, folder location, expected output keys, task ID, and task options. +/// </summary> +public record ProcessData { - /// <summary> - /// Represents all the parameters needed to launch a process : communication token, payload and session IDs, configuration settings, data dependencies, folder location, expected output keys, task ID, and task options. - /// </summary> - public record ProcessData - { - public string CommunicationToken { get; init; } - public string PayloadId { get; init; } - public string SessionId { get; init; } - public Configuration Configuration { get; init; } - public ICollection<string> DataDependencies { get; init; } - public string DataFolder { get; init; } - public ICollection<string> ExpectedOutputKeys { get; init; } - public string TaskId { get; init; } - public TaskOptions TaskOptions { get; init; } - } + public string? CommunicationToken { get; init; } + public string? PayloadId { get; init; } + public string? SessionId { get; init; } + public Configuration? Configuration { get; init; } + public ICollection<string>? DataDependencies { get; init; } + public string? DataFolder { get; init; } + public ICollection<string>? ExpectedOutputKeys { get; init; } + public string? TaskId { get; init; } + public TaskOptions? TaskOptions { get; init; } +} +/// <summary> +/// Represents a result with its creation date, name, status, session ID, result ID, and optional data. +/// </summary> +public record Result +{ + public DateTime CreatedAt { get; set; } + public string? Name { get; set; } + public ResultStatus? Status { get; init; } + public string? SessionId { get; set; } + public string? ResultId { get; set; } + public byte[]? Data { get; set; } +} - /// <summary> - /// Represents a result with its creation date, name, status, session ID, result ID, and optional data. - /// </summary> - public record Result - { - public DateTime CreatedAt { get; set; } - public string Name { get; set; } - public ResultStatus Status { get; init; } - public string SessionId { get; set; } - public string ResultId { get; set; } - public byte[]? Data { get; set; } - } - - /// <summary> - /// Represents task data, including its data dependencies, expected output keys, payload ID, and task ID. - /// </summary> - public record TaskData - { - public ICollection<string> DataDependencies { get; set; } - public ICollection<string> ExpectedOutputKeys { get; set; } - public string PayloadId { get; set; } - public string TaskId { get; set; } - } -} \ No newline at end of file +/// <summary> +/// Represents task data, including its data dependencies, expected output keys, payload ID, and task ID. +/// </summary> +public record TaskData +{ + public ICollection<string>? DataDependencies { get; set; } + public ICollection<string>? ExpectedOutputKeys { get; set; } + public string? PayloadId { get; set; } + public string? TaskId { get; set; } +}