Commit a26d8e67 authored by Bas Lijnse's avatar Bas Lijnse

Merge branch 'master' into destroy-on-halt

parents 659fe381 3392d393
Pipeline #43907 passed with stage
in 7 minutes and 14 seconds
......@@ -60,12 +60,14 @@ Tests/Interactive/GenericEditors/TestReal
Tests/Interactive/GenericEditors/TestRecordWithADT
Tests/Interactive/GenericEditors/TestSingleRecord
Tests/Interactive/GenericEditors/TestString
Tests/TestAsyncTask
Tests/Unit/iTasks.Extensions.Process.UnitTests
Tests/Unit/iTasks.Internal.IWorld.UnitTests
Tests/Unit/iTasks.Internal.TaskStore.UnitTests
Tests/Unit/iTasks.UI.Editor.Generic.UnitTests
Tests/Unit/iTasks.UI.Layout.UnitTests
Tests/Unit/iTasks.WF.Combinators.Common.UnitTests
Tests/Unit/iTasks.WF.Combinators.Core.UnitTests
Tests/Unit/iTasks.WF.Tasks.Core.UnitTests
Tests/Unit/iTasks.WF.Tasks.IO.UnitTests
Tools/CodeQualityMonitor
......
test:
linux-x64:
image: "camilstaps/clean:nightly"
before_script:
- install_clean.sh bundle-complete
- apt-get update -qq
- apt-get install -y -qq build-essential libsqlite3-dev libmariadbclient-dev-compat
script:
- bash ci-tests.bash
- bash Tests/posix.sh
artifacts:
when: always
paths:
- Tests/Unit/*-junit.xml
reports:
junit: Tests/Unit/*-junit.xml
linux-x86:
only:
- master
image: "camilstaps/clean:nightly"
before_script:
- CLEAN_PLATFORM=x86 install_clean.sh bundle-complete
- apt-get update -qq
- apt-get install -y -qq build-essential libsqlite3-dev:i386 libmariadbclient-dev-compat:i386
- sed -i 's/x64/x86/g' Tests/posix.sh
script:
- bash Tests/posix.sh
artifacts:
when: always
paths:
- Tests/Unit/*-junit.xml
reports:
junit: Tests/Unit/*-junit.xml
windows-x64:
only:
- master
tags:
- windows
- x64
before_script:
- wget -UseBasicParsing -o clean.zip https://ftp.cs.ru.nl/Clean/builds/windows-x64/clean-bundle-complete-windows-x64-latest.zip
- 7z x clean.zip
- sed -n -i '/EnvironmentName:\tiTasks/q;p' clean-bundle-complete\Config\IDEEnvs
- $EscapedPwd = $Pwd -replace '\\', '\\\\'
- tail -n +3 Config\windows-x64\iTasks.env | sed "s/\{Application\}.*iTasks/$EscapedPwd\\\\Libraries/" | Out-File -encoding ASCII -Append clean-bundle-complete\Config\IDEEnvs
- $Env:CLEAN_HOME = "$Pwd\\clean-bundle-complete"
- $Env:Path += ";${Env:CLEAN_HOME}"
script:
- bash Tests/windows.sh
artifacts:
when: always
paths:
......
......@@ -35,7 +35,7 @@ Global
Link
LinkMethod: Static
GenerateRelocations: False
GenerateSymbolTable: False
GenerateSymbolTable: True
GenerateLinkMap: False
LinkResources: False
ResourceSource:
......
Version: 1.0
Environment
EnvironmentName: iTasks-dist
EnvironmentPaths
Path: {Application}/lib/StdEnv
Path: {Application}/lib/Dynamics
Path: {Application}/lib/TCPIP
Path: {Application}/lib/ABCInterpreter
Path: {Application}/lib/GraphCopy
Path: {Application}/lib/Platform
Path: {Application}/lib/Platform/Deprecated/Generics
Path: {Application}/lib/Platform/Deprecated/StdLib
Path: {Application}/Development/iTasks-SDK/Libraries
EnvironmentCompiler: lib/exe/cocl-itasks::-dynamics -d
EnvironmentCodeGen: lib/exe/cg
EnvironmentLinker: /usr/bin/gcc::-g -Wl,--gc-sections|lib/exe/itasks-web-collector
EnvironmentABCOptimise: lib/exe/abcopt
EnvironmentByteCodeGen: lib/exe/bcgen
EnvironmentByteCodeLink: lib/exe/bclink
EnvironmentByteCodeStrip: lib/exe/bcstrip
EnvironmentByteCodePrelink: lib/exe/bcprelink
EnvironmentVersion: 920
EnvironmentRedirect: False
EnvironmentCompileMethod: Pers
EnvironmentProcessor: I386
Environment64BitProcessor: True
Version: 1.0
Environments
Environment
EnvironmentName: iTasks Tonic
EnvironmentPaths
Path: {Application}/lib/StdEnv
Path: {Application}/lib/Dynamics
Path: {Application}/lib/TCPIP
Path: {Application}/lib/Platform
Path: {Application}/lib/Platform/Deprecated/Generics
Path: {Application}/lib/Platform/Deprecated/StdLib
Path: {Application}/lib/ABCInterpreter
Path: {Application}/lib/GraphCopy
Path: {Application}/lib/iTasks
EnvironmentCompiler: lib/exe/cocl-tonic:-dynamics -tonic
EnvironmentCodeGen: lib/exe/cg
EnvironmentLinker: /usr/bin/gcc::-Wl,--gc-sections|lib/exe/itasks-web-collector
EnvironmentABCOptimise: lib/exe/abcopt
EnvironmentByteCodeGen: lib/exe/bcgen
EnvironmentByteCodeLink: lib/exe/bclink
EnvironmentByteCodeStrip: lib/exe/bcstrip
EnvironmentByteCodePrelink: lib/exe/bcprelink
EnvironmentVersion: 920
EnvironmentRedirect: False
EnvironmentCompileMethod: Pers
EnvironmentProcessor: I386
Environment64BitProcessor: True
......@@ -12,6 +12,7 @@ Environments
Path: {Application}/lib/ABCInterpreter
Path: {Application}/lib/GraphCopy
Path: {Application}/lib/iTasks
Path: {Application}/lib/Gast
EnvironmentCompiler: lib/exe/cocl-itasks::-dynamics
EnvironmentCodeGen: lib/exe/cg
EnvironmentLinker: /usr/bin/gcc::-Wl,--gc-sections|:linker:lib/exe/itasks-web-collector
......
......@@ -12,9 +12,9 @@ Environments
Path: {Application}/lib/ABCInterpreter
Path: {Application}/lib/GraphCopy
Path: {Application}/lib/iTasks
EnvironmentCompiler: lib/exe/cocl-itasks:-dynamics -desc -exl -d
EnvironmentCompiler: lib/exe/cocl-itasks::-dynamics
EnvironmentCodeGen: lib/exe/cg
EnvironmentLinker: /usr/bin/gcc|lib/exe/itasks-web-collector
EnvironmentLinker: /usr/bin/gcc::-Wl,--gc-sections -m32|:linker:lib/exe/itasks-web-collector
EnvironmentABCOptimise: lib/exe/abcopt
EnvironmentByteCodeGen: lib/exe/bcgen
EnvironmentByteCodeLink: lib/exe/bclink
......@@ -24,4 +24,4 @@ Environments
EnvironmentRedirect: False
EnvironmentCompileMethod: Pers
EnvironmentProcessor: I386
Environment64BitProcessor: True
Environment64BitProcessor: False
Version: 1.0
Environments
Environment
EnvironmentName: iTasks Tonic
EnvironmentPaths
Path: {Application}/lib/StdEnv
Path: {Application}/lib/Dynamics
Path: {Application}/lib/TCPIP
Path: {Application}/lib/Platform
Path: {Application}/lib/Platform/Deprecated/Generics
Path: {Application}/lib/Platform/Deprecated/StdLib
Path: {Application}/lib/ABCInterpreter
Path: {Application}/lib/GraphCopy
Path: {Application}/lib/iTasks
EnvironmentCompiler: lib/exe/cocl-tonic::-dynamics -tonic
EnvironmentCodeGen: lib/exe/cg
EnvironmentLinker: /usr/bin/gcc|lib/exe/itasks-web-collector
EnvironmentABCOptimise: lib/exe/abcopt
EnvironmentByteCodeGen: lib/exe/bcgen
EnvironmentByteCodeLink: lib/exe/bclink
EnvironmentByteCodeStrip: lib/exe/bcstrip
EnvironmentByteCodePrelink: lib/exe/bcprelink
EnvironmentVersion: 920
EnvironmentRedirect: False
EnvironmentCompileMethod: Pers
EnvironmentProcessor: I386
Environment64BitProcessor: True
# Parallelization #
## Introduction ##
This guide provides insights on how to write iTasks programs that execute on multiple processor cores/processors/machines.
## Parallel primitives ##
### Distributed engine ###
The distributed engine can be enabled using:
- `EngineOptions.distributed :: Maybe Int` (`--distributed PORT`)
This option either disables the distributed engine (`Nothing`) or enables it and offers distributed communication via the given port number.
- `EngineOptions.distributedChild :: Bool`
This option starts the process in child mode.
In child mode, the engine does not start any tasks except for the tasks required to function as a distributed iTasks node.
The command line option `--distributedChild PORT` enables child mode and enables distributed communication via the given port number.
### Shared Data Sources ###
SDSs of different processes can be accessed using the `remoteShare` primitive:
```Clean
:: SDSShareOptions =
{ domain :: !String
, port :: !Int
}
remoteShare :: (sds p r w) SDSShareOptions -> SDSRemoteSource p r w | RWShared sds
```
### Tasks ###
Executing tasks on a different machine can be done using the `asyncTask` primitive:
```Clean
asyncTask :: !String !Int !(Task a) -> Task a | iTask a
```
There are no limitations to what you can execute on a different machine.
Do keep in mind that if you want to access SDSs from the parent, they need to be remote again.
The UI of the task is presented on the parent server.
Also, if you want to do a blocking calculation, make sure it is evaluated on the client and not already on the server.
To make sure this happen you can wrap the task:
```Clean
task = asyncTask
"localhost"
8000
(return () >>- \_->return (somethingBlocking 42))
```
## Troubleshooting ##
When encountering problems ask yourself the following questions first:
- Are the correct project file options set? (`Link.GenerateSymbolTable` and `Application.Profile.DescExL`)
- Are the binaries of the server and the client compiled from the exact same source?
......@@ -13,7 +13,9 @@
allows the next optimization:
- Think about which guards/patterns are the most common cases and put those
first.
first. For ADTs with two constructors, it does not matter which is matched
first: in either case, one descriptor equality check will be done (if
unequal, it is assumed that the value is of the other constructor).
- Avoid unnecessary pointfree notation (e.g., do not write `const ((===) key)`
but write `\_ k -> k == key`.
......
......@@ -139,7 +139,7 @@ toLeafletMap {ContactMap|perspective,layers}
,objects = []
}
where
tilesUrls layers = [url \\ {ContactMapLayer|def=CMTileLayer url} <- layers]
tilesUrls layers = [{url = url, attribution = Nothing} \\ {ContactMapLayer|def=CMTileLayer url} <- layers]
convMarkers markers = [conv m \\ m=:{ContactMapMarker|position} <- markers | hasLatLng position]
conv {ContactMapMarker|markerId,title,position,heading,type}
......
definition module Incidone.Integration.AIS
import iTasks, Incidone.Util.AIS
import iTasks, Message.Encodings.AIS
//Connect to an external AIS Server that streams AIVDM messages
syncAISStream :: Task ()
......
implementation module Incidone.Integration.AIS
import iTasks
import Incidone.Util.AIS
import Message.Encodings.AIS
import Incidone.Configuration
import Incidone.OP.SDSs, Incidone.OP.Conversions
import Incidone.Util.TaskPatterns
......
concept module Incidone.OP.Concepts
import iTasks, iTasks.Extensions.Document, iTasks.Extensions.Contact, Database.SQL, Incidone.OP.ConceptsTOP, Incidone.OP.ConceptsSQL, Incidone.ContactPosition, Incidone.Util.AIS
import iTasks, iTasks.Extensions.Document, iTasks.Extensions.Contact, Database.SQL, Incidone.OP.ConceptsTOP, Incidone.OP.ConceptsSQL, Incidone.ContactPosition, Message.Encodings.AIS
//Shared value types
$$ MMSI = Int
......
definition module Incidone.OP.Concepts
//GENERATED BY CCL, DO NOT EDIT
import iTasks, iTasks.Extensions.Document, iTasks.Extensions.Contact, Database.SQL, Incidone.OP.ConceptsTOP, Incidone.OP.ConceptsSQL, Incidone.ContactPosition, Incidone.Util.AIS
import iTasks, iTasks.Extensions.Document, iTasks.Extensions.Contact, Database.SQL, Incidone.OP.ConceptsTOP, Incidone.OP.ConceptsSQL, Incidone.ContactPosition, Message.Encodings.AIS
:: AISStaticInfo :== AIVDM5
......
implementation module Incidone.OP.Concepts
//GENERATED BY CCL, DO NOT EDIT
import iTasks, Database.SQL, Incidone.OP.ConceptsTOP, Incidone.OP.ConceptsSQL, Incidone.ContactPosition, Incidone.Util.AIS
import iTasks, Database.SQL, Incidone.OP.ConceptsTOP, Incidone.OP.ConceptsSQL, Incidone.ContactPosition, Message.Encodings.AIS
instance mbToSQL Int
where
......
......@@ -14,6 +14,7 @@ import Text, Text.HTML, Data.Either, Data.Functor
import iTasks.UI.Editor.Controls
derive gDefault Contact, ContactMap, ContactStatus, ContactAccessLevel, Credentials, ContactPhoto, ContactTrack, ContactType, Degrees, Document, ContactMapLayer, DateTime, ContactMapLayerDefinition, ContactMapMarker, ContactMapRegion, ContactMapMarkerType
derive gHash ContactMapPerspective, Credentials
CONVERT_BIN :== "/opt/local/bin/convert"
//CONVERT_BIN :== "/usr/bin/convert"
......
......@@ -150,7 +150,7 @@ aisPosition :: AIVDMCNB -> ContactPosition
aisPosition {AIVDMCNB|lat,lon} = PositionLatLng (toReal lat / 600000.0, toReal lon / 600000.0)
aisHeading :: AIVDMCNB -> ContactHeading
aisHeading {AIVDMCNB|heading} = Degrees heading
aisHeading {AIVDMCNB|heading} = Degrees (fromMaybe 0 heading)
updAISContactPosition :: DateTime ContactPosition ContactHeading AISContact -> AISContact
updAISContactPosition now nposition nheading c=:{AISContact|position,heading,track,positionUpdated}
......
......@@ -10,6 +10,7 @@ import Incidone.OP.Concepts
{filterByName :: Maybe String
}
derive class iTask ContactFilter
derive gHash ContactFilter
allContactPhotos :: SimpleSDSLens (Map ContactNo [ContactPhoto])
lastAISImport :: SimpleSDSLens (Maybe (DateTime,String,Int))
......
......@@ -10,6 +10,7 @@ import Data.Functor, Data.Either, Data.Tuple, Data.Func
derive class iTask ContactFilter
derive gDefault PhoneCall, RadioCall, EmailMessage, P2000Message, WeatherData, PersonDetails, VesselDetails, SurferDetails, DiverDetails, AirplaneDetails, HelicopterDetails, CommunicationMean, WeatherType, Gender, VesselType, CommunicationMeanType, Feet, Knots, Meters, Temperature, Degrees, Miles
derive gHash ContactFilter, Credentials, RowFilterDef, QueryDef, RowOrderDef, ColumnSourceDef, TableDef
dbReadSDS :: String -> SDSSequence QueryDef [r] () | mbFromSQL r & TC r
dbReadSDS notifyId = databaseDef >++> sqlReadSDS notifyId
......
definition module Incidone.Util.AIS
/**
* This module provides functions for decoding a stream of AIVDM/AIVDO messages.
* These messages transmitted by AIS (Automatic Identification System) radio receivers.
*
* This module is based on the information provided at:
* http://gpsd.berlios.de/AIVDM.html
* and the python ais.py decoder of the gpsd project
*
* Currently this module only decodes type 1-5 messages. All other message types are ignored
*/
// AIVDM Message data
:: AIVDM
= AIVDM1 AIVDMCNB
| AIVDM2 AIVDMCNB
| AIVDM3 AIVDMCNB
| AIVDM4 AIVDM4
| AIVDM5 AIVDM5
| AIVDM Int //An unsupported message type
:: AIVDMCNB = //Common Navigation Block (data for messages type 1,2 and 3)
{ msgtype :: Int // Message Type
, repeat :: Int // Repeat Indicator
, mmsi :: Int // MMSI
, status :: Int // Navigation Status
, turn :: Int // Rate of Turn
, speed :: Int // Speed Over Ground
, accuracy :: Bool // Position Accuracy
, lon :: Int // Longitude
, lat :: Int // Latitude
, course :: Int // Course Over Ground
, heading :: Int // True Heading
, second :: Int // Time Stamp
, maneuver :: Int // Manuever Indicator
, raim :: Bool // RAIM flag
, radio :: Int // Radio status
}
:: AIVDM4 = //Type 4 message (Base station report)
{ msgtype :: Int // Message Type
, repeat :: Int // Repeat Indicator
, mmsi :: Int // MMSI
, year :: Int // Year
, month :: Int // Month
, day :: Int // Day
, hour :: Int // Hour
, minute :: Int // Minute
, second :: Int // Second
, accuracy :: Bool // Fix quality
, lon :: Int // Longitude
, lat :: Int // Latitude
, epfd :: Int // Type of EPFD
, raim :: Bool // RAIM flag
, radio :: Int // SOTDMA state
}
:: AIVDM5 = //Type 5 message (Static and Voyage Related data)
{ msgtype :: Int // Message type
, repeat :: Int // Repeat Indicator
, mmsi :: Int // MMSI
, ais_version :: Int // AIS Version
, imo_id :: Int // IMO Identification Number
, callsign :: String // Call Sign
, shipname :: String // Vessel Name
, shiptype :: Int // Ship Type
, to_bow :: Int // Dimension to Bow
, to_stern :: Int // Dimension to Stern
, to_port :: Int // Dimension to Port
, to_starboard :: Int // Dimension to Starboard
, epfd :: Int // Position Fix Type
, month :: Int // ETA month
, day :: Int // ETA day
, hour :: Int // ETA hour
, minute :: Int // ETA minute
, draught :: Int // Draught
, destination :: String // Destination
, dte :: Bool // DTE
}
/**
* Decodes a series of encoded AIVDM sentences to a series of
* decoded messages. AIVDM is the message format used by AIS
* AIVDM messages can consist of multiple sentences, so only full messages
* are parsed. If there are sentences of yet incomplete messages they are returned
*/
decodeAIVDM :: [String] -> ([AIVDM],[String])
implementation module Incidone.Util.AIS
/**
* This module provides functions for decoding a stream of AIVDM/AIVDO messages.
* These messages transmitted by AIS (Automatic Identification System) radio receivers.
*
* This module is based on the information provided at:
* http://gpsd.berlios.de/AIVDM.html
* and the python ais.py decoder of the gpsd project
*
* Currently this module only decodes type 1-5 messages. All other message types are ignored
*/
import StdBool, StdInt, StdString, StdTuple, StdArray, StdClass, StdList, Text, Data.Maybe
TESTMESSAGES :==
["!AIVDM,1,1,,,339K5fUP080PrBtNQQjua7Qn0000,0*57"
,"!AIVDM,2,1,1,,539K5fP00000@95>221M=236222222222222220o1@D222v0051CA1C`8888,0*2C"
,"!AIVDM,2,2,1,,88888888888,2*6C"
,"!AIVDM,1,1,,,13aBLohP000DCV4MdGlf3@020000,0*1D"
,"!AIVDM,2,1,1,,53aBLoh0SPpE0K;33N0lE8=E8UE>04m=@E8@4n169P:382Ec08lSm51DQ0CH,0*34"
,"!AIVDM,2,2,1,,88888888888,2*6C"
]
// AIVDM Message data
:: AIVDM
= AIVDM1 AIVDMCNB
| AIVDM2 AIVDMCNB
| AIVDM3 AIVDMCNB
| AIVDM4 AIVDM4
| AIVDM5 AIVDM5
| AIVDM Int //An unsupported message type
:: AIVDMCNB = //Common Navigation Block (data for messages type 1,2 and 3)
{ msgtype :: Int // Message Type
, repeat :: Int // Repeat Indicator
, mmsi :: Int // MMSI
, status :: Int // Navigation Status
, turn :: Int // Rate of Turn
, speed :: Int // Speed Over Ground
, accuracy :: Bool // Position Accuracy
, lon :: Int // Longitude
, lat :: Int // Latitude
, course :: Int // Course Over Ground
, heading :: Int // True Heading
, second :: Int // Time Stamp
, maneuver :: Int // Manuever Indicator
, raim :: Bool // RAIM flag
, radio :: Int // Radio status
}
:: AIVDM4 = //Type 4 message (Base station report)
{ msgtype :: Int // Message Type
, repeat :: Int // Repeat Indicator
, mmsi :: Int // MMSI
, year :: Int // Year
, month :: Int // Month
, day :: Int // Day
, hour :: Int // Hour
, minute :: Int // Minute
, second :: Int // Second
, accuracy :: Bool // Fix quality
, lon :: Int // Longitude
, lat :: Int // Latitude
, epfd :: Int // Type of EPFD
, raim :: Bool // RAIM flag
, radio :: Int // SOTDMA state
}
:: AIVDM5 = //Type 5 message (Static and Voyage Related data)
{ msgtype :: Int // Message type
, repeat :: Int // Repeat Indicator
, mmsi :: Int // MMSI
, ais_version :: Int // AIS Version
, imo_id :: Int // IMO Identification Number
, callsign :: String // Call Sign
, shipname :: String // Vessel Name
, shiptype :: Int // Ship Type
, to_bow :: Int // Dimension to Bow
, to_stern :: Int // Dimension to Stern
, to_port :: Int // Dimension to Port
, to_starboard :: Int // Dimension to Starboard
, epfd :: Int // Position Fix Type
, month :: Int // ETA month
, day :: Int // ETA day
, hour :: Int // ETA hour
, minute :: Int // ETA minute
, draught :: Int // Draught
, destination :: String // Destination
, dte :: Bool // DTE
}
decodeAIVDM :: [String] -> ([AIVDM],[String])
decodeAIVDM [] = ([],[])
decodeAIVDM sentences
# (payload, remainder) = decodeWrapper sentences
= case payload of
[] = ([],remainder)
parts
# cnb = decodePayload (concat parts)
# (cnbs,remainder) = decodeAIVDM remainder
= ([cnb:cnbs],remainder)
where
//Take a number of fragments from the stream to unwrap and reconstruct the message payload
decodeWrapper :: [String] -> ([{#Char}], [String])
decodeWrapper [] = ([],[])
decodeWrapper [sentence:remainder]
= case split "," sentence of
[f1,f2,f3,f4,f5,f6,f7]
| f1 <> "!AIVDM"
= ([],remainder)
# fragmentCount = toInt f2
# fragmentNum = toInt f3
| fragmentCount == fragmentNum
= ([f6],remainder)
| otherwise
# (fragments,remainder) = decodeWrapper remainder
= ([f6:fragments],remainder)
_ = ([],remainder)
//Decode the message data
decodePayload :: {#Char} -> AIVDM
decodePayload bits
# bits = bv_unarmor bits
= snd ((decodeDyn decodeMsgType decoderByType) bits 0 (AIVDM 0))
where
decodeMsgType = decodeUnsigned 6 (\t _ -> initMessage t)
decoderByType msg = case msg of
AIVDM1