Skip to content

Commit

Permalink
Merge pull request #25 from Assassyn/feature/infinit-run-in-cli
Browse files Browse the repository at this point in the history
Feature/infinit run in cli
  • Loading branch information
Assassyn authored May 24, 2023
2 parents 6acaa55 + 3ede62e commit d5f9ead
Show file tree
Hide file tree
Showing 30 changed files with 169 additions and 135 deletions.
2 changes: 1 addition & 1 deletion build/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ trigger:
pool:
vmImage: ubuntu-latest

name: 0.7.0-$(Rev:r)
name: 0.8.0-$(Rev:r)

stages:
- stage: BuildAndTest
Expand Down
6 changes: 6 additions & 0 deletions src/Functional.ETL/Pipeline.fs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ module Pipeline =
let withResult<'Result> (entity: PipelineProcessData<'Result>) (value: 'Result) =
let results = value::entity.results
{ entity with results = results }

let (|>=) entity result = withResult entity result
let (|=>) result entity = withResult entity result
let (>=>) entity result = withResult entity result
let (<=<) result entity = withResult entity result

let readProperty entity key =
match entity.properties.ContainsKey (key) with
| true -> Some entity.properties.[key]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
</PropertyGroup>

<ItemGroup>
<Compile Include="Logging.fs" />
<Content Include="configuration.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Compile Include="Program.fs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Lamar" Version="12.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="7.0.0" />
</ItemGroup>

Expand Down
15 changes: 15 additions & 0 deletions src/Functional.UniversalBot.CLI/Logging.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module Logging

open Functional.ETL.Pipeline
open PipelineResult
open Lamar

let logger (entity: PipelineProcessData<PipelineResult.UniversalHiveBotResutls>) =
let lastMessage = entity.results.Head
printfn "%O" lastMessage
entity

type ActionRegistry () as self =
inherit ServiceRegistry ()
do
self.For<Transformer<PipelineResult.UniversalHiveBotResutls>>().Use(logger).Named("decorator") |> ignore
46 changes: 20 additions & 26 deletions src/Functional.UniversalBot.CLI/Program.fs
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
open Configuration
open Configuration
open PipelineResult
open Functional.ETL.Pipeline

let printResults (processedData: PipelineProcessData<UniversalHiveBotResutls> array) =
processedData
|> Seq.collect (fun x -> x.results)
|> Seq.iter (fun result -> printfn "%O" result)

let getlastResult (entity:PipelineProcessData<UniversalHiveBotResutls>) =
match entity.results.IsEmpty with
| false -> Some entity.results.[^0]
| _ -> None
let action () =
printfn "Starting UniveralHiveBot processs"
let config = getConfiguration ()

let logger moduleName user token =
printfn "%s: %s: %s" moduleName user token

printfn "Starting UniveralHiveBot processs"

let config = getConfiguration ()

match config.actions with
| null ->
printfn "no actions found"
| _ ->
printfn "found %i actions to execute" (config.actions |> Seq.length)
let pipelines = createPipelines config logger
pipelines
|> Seq.iter (fun x -> processPipeline x |> ignore)

printfn "Finshed UniveralHiveBot processs"
match config.actions with
| null ->
"no actions found"
| _ ->
printfn "found %i actions to execute" (config.actions |> Seq.length)
let pipelines = createPipelines config
pipelines
|> Seq.iter (fun x -> processPipeline x |> ignore)
"Finshed UniveralHiveBot processs"

let readlines = Seq.initInfinite (fun _ -> action())

let run item =
item = "quit"

Seq.find run readlines |> ignore
2 changes: 1 addition & 1 deletion src/Functional.UniversalBot.Core/AmountCalator.fs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ let private (|Calculation|_|) (str: string) =
else None
else None

let bind (value: string) =
let bind (value: string): decimal -> decimal =
let calculation =
match value with
| StaticValue x -> x
Expand Down
4 changes: 1 addition & 3 deletions src/Functional.UniversalBot.Core/Configuration.Types.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
open Types
open Functional.ETL.Pipeline

type Loger = string -> string -> string -> unit

type Binder = Loger -> Urls -> Map<string, string> -> Transformer<PipelineResult.UniversalHiveBotResutls>
type Binder = Urls -> Map<string, string> -> Transformer<PipelineResult.UniversalHiveBotResutls>

type UserActionReader = UserActionsDefinition seq -> Reader<PipelineResult.UniversalHiveBotResutls>
37 changes: 26 additions & 11 deletions src/Functional.UniversalBot.Core/Configuration.fs
Original file line number Diff line number Diff line change
Expand Up @@ -30,33 +30,48 @@ let private container =
scanner.LookForRegistries ()))

let private getActionByName (name: string) =
let actionBuilder = container.GetInstance<Binder> (name.ToLower ())
actionBuilder
let binder = container.TryGetInstance<Binder> (name.ToLower ())
if binder :> obj = null
then
fun urls properties -> (fun entity -> entity)
else
binder

let private bindActions logger url parameters bindingFunctionName =
let private getActionDecorator () =
let actionDecorator = container.TryGetInstance<Transformer<PipelineResult.UniversalHiveBotResutls>> ("decorator")
if actionDecorator :> obj = null
then
fun entity -> entity
else
actionDecorator

let private bindActions url parameters bindingFunctionName =
let prototypeFunction = (getActionByName bindingFunctionName)
let pipelineAction = prototypeFunction logger url parameters
let pipelineAction = prototypeFunction url parameters
pipelineAction

let private bindTransfomers logger url (config: UserActionsDefinition) =
let private bindTransfomers url (config: UserActionsDefinition) =
let binder fromConfig =
let (bindingFunctionName, parameters ) = fromConfig
bindActions logger url parameters bindingFunctionName
bindActions url parameters bindingFunctionName

let actionDecorator = getActionDecorator ()

config.Tasks
|> Seq.collect splitToActualActionConfigurationItems
|> List.ofSeq
|> List.map (fun item -> (item.Name, item.Parameters |> Seq.map (|KeyValue|) |> Map.ofSeq))
|> List.map (fun item -> binder item)
|> List.fold (fun state next -> state >> next) Transformer.defaultTransformer<PipelineResult.UniversalHiveBotResutls>
|> List.fold (fun state next -> state >> next >> actionDecorator) Transformer.defaultTransformer<PipelineResult.UniversalHiveBotResutls>

let private bindPipeline logger urls (config: UserActionsDefinition) =
let private bindPipeline urls (config: UserActionsDefinition) =
let reader = container.GetInstance<UserActionReader>()
let transforms = bindTransfomers logger urls config
let transforms = bindTransfomers urls config

Pipeline.bind (reader [config]) transforms

let createPipelines (config: Configuration) logger =
let createPipelines (config: Configuration) =
let urls = config.urls

config.actions
|> Seq.map (bindPipeline logger urls)
|> Seq.map (bindPipeline urls)
5 changes: 4 additions & 1 deletion src/Functional.UniversalBot.Core/PipelineResult.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ type Message = string
type TransactionId = string
type CustomJson = HiveAPI.COperations.custom_json
type Token = string
type Username = string
type KeyRequired =
| Active
| Posting

type UniversalHiveBotResutls =
| Unknow
| NoUserDetails of Module
| TokenBalanceLoaded of Username
| HiveOperation of Module * Token * KeyRequired * CustomJson
| TokenBalanceTooLow of Module * Token
| FlushingFinshed of Username * UniversalHiveBotResutls seq
| TokenBalanceTooLow of Module * Username * Token
| Processed of Module * Item
| UnableToProcess of Module * Item * Message
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ open Functional.ETL.Pipeline
type ActionRegistry () as self =
inherit ServiceRegistry ()
do
let defaultBinder = (fun logger url properties -> Transformer.defaultTransformer<PipelineResult.UniversalHiveBotResutls>)
let defaultBinder = (fun url properties -> Transformer.defaultTransformer<PipelineResult.UniversalHiveBotResutls>)
self.For<Binder>().Use(StakeToken.bind).Named("stake") |> ignore
self.For<Binder>().Use(UnstakeToken.bind).Named("unstake") |> ignore
self.For<Binder>().Use(DelegateStake.bind).Named("delegatestake") |> ignore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ let buildCustomJson username method payload =
let json = System.Text.Json.JsonSerializer.Serialize (payload)
Hive.createCustomJsonActiveKey username method json

let scheduleActiveOperation logger moduleName tokenSymbol operation =
logger tokenSymbol
let scheduleActiveOperation moduleName tokenSymbol operation =
HiveOperation (moduleName, tokenSymbol, KeyRequired.Active, operation)

type CustomJsonMessage<'Payload> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ let private splitPair (tokenPair: string) =
let parts = tokenPair.Split(":")
(parts[0], parts[1])

let private scheduleTokenToPoolTransfer logger username tokenPair baseQuantity quoteQuantity =
let private scheduleTokenToPoolTransfer username tokenPair baseQuantity quoteQuantity =
bindCustomJson
"marketpools"
"addLiquidity"
Expand All @@ -28,9 +28,9 @@ let private scheduleTokenToPoolTransfer logger username tokenPair baseQuantity q
maxDeviation = "0"
|}
|> buildCustomJson username "ssc-mainnet-hive"
|> scheduleActiveOperation (logger username) ModuleName tokenPair
|> scheduleActiveOperation ModuleName tokenPair

let action logger hive hiveEngineUrl tokenPair leftAmountCalculator rightAmountCalculator (entity: PipelineProcessData<UniversalHiveBotResutls>) =
let action hive hiveEngineUrl tokenPair leftAmountCalculator rightAmountCalculator (entity: PipelineProcessData<UniversalHiveBotResutls>) =
let userDetails: (string * string * string) option = PipelineProcessData.readPropertyAsType entity "userdata"

match userDetails with
Expand Down Expand Up @@ -58,16 +58,16 @@ let action logger hive hiveEngineUrl tokenPair leftAmountCalculator rightAmountC

match (leftTokenBaseAmount, leftTokenQuoteAmount, rightTokenBaseAmount, rightTokenQuoteAmount) with
| (leftBase, leftQuote, _, _) when leftBase > 0M && leftQuote > 0M && leftBase <= leftTokenBaseAmount && leftQuote <= rightTokenBaseAmount ->
scheduleTokenToPoolTransfer logger username tokenPair leftBase leftQuote |> withResult entity
scheduleTokenToPoolTransfer username tokenPair leftBase leftQuote |> withResult entity
| (_, _, rightBase, rightQuote) when rightBase > 0M && rightQuote > 0M && rightBase <= rightTokenBaseAmount && rightQuote <= leftTokenBaseAmount ->
scheduleTokenToPoolTransfer logger username tokenPair rightQuote rightBase |> withResult entity
scheduleTokenToPoolTransfer username tokenPair rightQuote rightBase |> withResult entity
| _ ->
TokenBalanceTooLow (ModuleName, tokenPair) |> withResult entity
TokenBalanceTooLow (ModuleName, username, tokenPair) |> withResult entity
| _ ->
NoUserDetails ModuleName |> PipelineProcessData.withResult entity

let bind logger (urls: Urls) (parameters: Map<string, string>) =
let bind (urls: Urls) (parameters: Map<string, string>) =
let tokenPair = parameters.["tokenPair"]
let leftAmount = parameters.["leftAmount"] |> AmountCalator.bind
let rightAmount = parameters.["rightAmount"] |> AmountCalator.bind
action (logger ModuleName) urls.hiveNodeUrl urls.hiveEngineNodeUrl tokenPair leftAmount rightAmount
action urls.hiveNodeUrl urls.hiveEngineNodeUrl tokenPair leftAmount rightAmount
20 changes: 10 additions & 10 deletions src/Functional.UniversalBot.Plugin.HiveEngine/Actions/Balance.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ open HiveEngine
open Types
open PipelineResult
open Functional.ETL.Pipeline
open Functional.ETL.Pipeline.PipelineProcessData
open HiveEngineTypes

[<Literal>]
Expand All @@ -19,7 +20,7 @@ let private addProperty tokenSymbol tokenBalance entity =
let private addTokensDetails tokenDetails entity =
PipelineProcessData.withProperty entity TokenInfo.TokenDetailsKey tokenDetails

let calculateStake tokenInfo pendingUnstakes =
let private calculateStake tokenInfo pendingUnstakes =
let stake = tokenInfo.stake
let tokenUnstakes: PendingUnstakes seq =
pendingUnstakes
Expand All @@ -34,36 +35,35 @@ let calculateStake tokenInfo pendingUnstakes =
|> Seq.fold (fun acc next -> acc + next) 0M
stake + quantityLeft - quantity

let calculateDelegatedStake tokenInfo =
let private calculateDelegatedStake tokenInfo =
let stake = tokenInfo.delegationsIn
let pendingUnstake = tokenInfo.pendingUndelegations
stake - pendingUnstake

let private hasAnyBalance (tokenInfo: TokenBalance) =
(tokenInfo.balance > 0M) || (tokenInfo.stake > 0M) || (tokenInfo.delegationsIn > 0M)

let private addTokenBalanceAsProperty logger pendingUnstakes entity (tokenInfo: TokenBalance) =
let private addTokenBalanceAsProperty pendingUnstakes entity (tokenInfo: TokenBalance) =
match hasAnyBalance tokenInfo with
| true ->
logger (sprintf "Loading balance for %s" tokenInfo.symbol)
entity
|> addProperty tokenInfo.symbol tokenInfo.balance
|> addProperty (tokenInfo.symbol+"_stake") (calculateStake tokenInfo pendingUnstakes)
|> addProperty (tokenInfo.symbol+"_delegatedstake") (calculateDelegatedStake tokenInfo)
| _ ->
entity

let action logger hiveEngineUrl (entity: PipelineProcessData<UniversalHiveBotResutls>) =
let action hiveEngineUrl (entity: PipelineProcessData<UniversalHiveBotResutls>) =
let username = PipelineProcessData.readPropertyAsString entity "username"

match username with
| Some username ->
getBalance hiveEngineUrl username
|> Seq.fold (addTokenBalanceAsProperty (logger username) (getPendingUnstakes hiveEngineUrl username)) entity
|> Seq.fold (addTokenBalanceAsProperty (getPendingUnstakes hiveEngineUrl username)) entity
|> addTokensDetails (getTokenDetails hiveEngineUrl)
|>= TokenBalanceLoaded username
| _ ->
NoUserDetails ModuleName
|> PipelineProcessData.withResult entity
NoUserDetails ModuleName <=< entity

let bind logger (urls: Urls) (parameters: Map<string, string>) =
action (logger ModuleName) urls.hiveEngineNodeUrl
let bind (urls: Urls) (parameters: Map<string, string>) =
action urls.hiveEngineNodeUrl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ open Functional.ETL.Pipeline.PipelineProcessData
[<Literal>]
let ModuleName = "DelegateStake"

let action logger tokenSymbol delegateTo amountCalcualtor (entity: PipelineProcessData<UniversalHiveBotResutls>) =
let action tokenSymbol delegateTo amountCalcualtor (entity: PipelineProcessData<UniversalHiveBotResutls>) =
let userDetails: (string * string * string) option = readPropertyAsType entity "userdata"

match userDetails with
Expand All @@ -28,15 +28,15 @@ let action logger tokenSymbol delegateTo amountCalcualtor (entity: PipelineProce
then
bindCustomJson "tokens" "delegate" {|``to`` = delegateTo;symbol = tokenSymbol;quantity = String.asString tokenBalance|}
|> buildCustomJson username "ssc-mainnet-hive"
|> scheduleActiveOperation (logger username) ModuleName tokenSymbol
|> scheduleActiveOperation ModuleName tokenSymbol
|> withResult entity
else
TokenBalanceTooLow (ModuleName, tokenSymbol) |> withResult entity
TokenBalanceTooLow (ModuleName, username, tokenSymbol) |> withResult entity
| _ ->
NoUserDetails ModuleName |> withResult entity

let bind logger urls (parameters: Map<string, string>) =
let bind urls (parameters: Map<string, string>) =
let token = parameters.["token"]
let delegateTo = parameters.["delegateTo"]
let amount = parameters.["amount"] |> AmountCalator.bind
action (logger ModuleName) token delegateTo amount
action token delegateTo amount
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ let private ModuleName = "FlushAndBalance"

let private waitTime = TimeSpan.FromSeconds (3)

let action logger hiveUrl hiveEngineUrl (entity: PipelineProcessData<UniversalHiveBotResutls>) =
FlushTokens.action logger hiveUrl entity
let action hiveUrl hiveEngineUrl (entity: PipelineProcessData<UniversalHiveBotResutls>) =
FlushTokens.action hiveUrl entity
|> (fun entity ->
Thread.Sleep (waitTime)
entity)
|> Balance.action logger hiveEngineUrl
|> Balance.action hiveEngineUrl

let bind logger urls (parameters: Map<string, string>) =
action (logger ModuleName) urls.hiveNodeUrl urls.hiveEngineNodeUrl
let bind urls (parameters: Map<string, string>) =
action urls.hiveNodeUrl urls.hiveEngineNodeUrl
Loading

0 comments on commit d5f9ead

Please sign in to comment.