MultiThreading in IOS Swift - ios

I am trying to run two threads in parallel. But unfortunately , it sometime works sometime not. Here is my code
let firstQueue = DispatchQueue(label: "queue1", qos: DispatchQoS.userInitiated)
let secondQueue = DispatchQueue(label: "queue2", qos: DispatchQoS.userInitiated)
//let firstQueue = DispatchQueue(label: "queue1", qos: DispatchQoS.default , attributes: .concurrent)
firstQueue.async {
for i in 0..<10 {
print("🔷", i)
}
}
secondQueue.async {
for i in 20..<30 {
print("⚪️", i)
}
}
I have tried different everything but not achieve perfect parallelism.
First Time Output: 0
⚪️ 20
🔷 1
⚪️ 21
🔷 2
⚪️ 22
🔷 3
⚪️ 23
🔷 4
⚪️ 24
🔷 5
⚪️ 25
🔷 6
⚪️ 26
🔷 7
⚪️ 27
🔷 8
⚪️ 28
🔷 9
⚪️ 29
SecondTime Output :
🔷 0
🔷 1
🔷 2
🔷 3
🔷 4
🔷 5
🔷 6
🔷 7
🔷 8
🔷 9
⚪️ 20
⚪️ 21
⚪️ 22
⚪️ 23
⚪️ 24
⚪️ 25
⚪️ 26
⚪️ 27
⚪️ 28
⚪️ 29

The point of multithreading is that operations will be done parallel and independent from one another. That does not guaranty any order at all, there is no synchronization, no nothing. If you need to have things synchronized then you will need to use a single thread or use a third thread that dispatches work:
func foo() {
let firstQueue = DispatchQueue(label: "queue1")
let secondQueue = DispatchQueue(label: "queue2")
let mainQueue = DispatchQueue(label: "queueMain")
var firstQueueOperationsCount: Int = 10
var secondQueueOperationsCount: Int = 10
func performOperations() {
guard max(firstQueueOperationsCount, secondQueueOperationsCount) > 0 else {
return
}
mainQueue.async {
if firstQueueOperationsCount > secondQueueOperationsCount {
firstQueueOperationsCount -= 1
firstQueue.async {
print("🔷")
performOperations()
}
} else {
secondQueueOperationsCount -= 1
secondQueue.async {
print("⚪️")
performOperations()
}
}
}
}
performOperations()
}
There are many ways on how to serialize tasks dispatched on multiple threads and this being just one of them. You might try searching/reading toward that direction but just be clear: What you seem to expect from multithreading is NOT WHAT MULTITHREADING IS. It does not work this way and it does not supposed to work this way. How they do work is how we want it to work.
If you have a more specific situation I am sure community here may help you identify a good approach to solve it. But from what you have written the result is not multithreading but:
for i in 0..<10 {
print("🔷")
print("⚪️")
}
It might be dispatched on another thread but that really makes no difference.

Your code works well, but the thing you should know is that, you haven't any choice to decide which part of your code execute first, and since your code is just printing a character and its a light job to do for cpu you see some times your characters printing ordered and some times unordered. Try to give some more heavy job to cpu and then see the results!

You can use DispatchGroup, also you should read more about GCD, the code below work as expected and it will fix your issue
let dispatchGroup = DispatchGroup()
let firstQueue = DispatchQueue(label: "queue1", qos: DispatchQoS.userInitiated)
let secondQueue = DispatchQueue(label: "queue2", qos: DispatchQoS.userInitiated)
firstQueue.async(group: dispatchGroup) {
for i in 0..<10 {
print("🔷", i)
}
dispatchGroup.leave()
}
secondQueue.async(group: dispatchGroup) {
dispatchGroup.wait()
for i in 20..<30 {
print("⚪️", i)
}
}
the output always will be like this 🔷 0
🔷 1
🔷 2
🔷 3
🔷 4
🔷 5
🔷 6
🔷 7
🔷 8
🔷 9
⚪️ 20
⚪️ 21
⚪️ 22
⚪️ 23
⚪️ 24
⚪️ 25
⚪️ 26
⚪️ 27
⚪️ 28
⚪️ 29

Related

Jenkins JobDSL ERROR: Found multiple extensions which provide method branchDiscoveryTrait with arguments []:

I'm using jenkins jobDSL plugin to generate my pipeline jobs from a groovy script, where I'm trying to create a multibranchPipelineJob as you can in the following line
17 multibranchPipelineJob("projects/${project_name}/${component_name}") {
18 branchSources {
19 branchSource {
20 source {
21 git {
22 remote(component.repository)
23 credentialsId(component.credentials)
24 traits {
25 branchDiscoveryTrait()
26 cleanBeforeCheckoutTrait()
27 }
28 }
29 }
30 strategy {
31 defaultBranchPropertyStrategy {
32 props {
33 }
34 }
35 }
36 }
37 }
38 triggers {
39 periodic(5)
40 }
41 orphanedItemStrategy {
42 discardOldItems {
43 // numToKeep(20)
44 }
45 }
46 if (component.jenkinsfile) {
47 factory {
48 workflowBranchProjectFactory {
49 scriptPath(component.jenkinsfile)
50 }
51 }
52 }
53 }
When the main pipeline job executing this code runs, it raises this (apparently know) error :
ERROR: Found multiple extensions which provide method
branchDiscoveryTrait with arguments []:
[[com.cloudbees.jenkins.plugins.bitbucket.BranchDiscoveryTrait,
jenkins.plugins.git.traits.BranchDiscoveryTrait,
org.jenkinsci.plugins.github_branch_source.BranchDiscoveryTrait]]
I've searched and see many results where people say that we should add #Symbol annotations to the traits implementations or to the relevant descriptors.
But I don't understand exactly what to do and where to place that #Symbol, people seem to say it solves the issue, but there is nowhere a good explanation and guidance to apply the fix.
should the modification be done in the plugin code or elsewhere?
I solved it by using the specific git scm class, and the correct syntax was :
17 multibranchPipelineJob("projects/${project_name}/${component_name}") {
18 branchSources {
19 branchSource {
20 source {
21 git {
22 remote(component.repository)
23 credentialsId(component.credentials)
24 traits {
25 gitBranchDiscovery()
26 cleanBeforeCheckoutTrait {
27 extension {
28 deleteUntrackedNestedRepositories(false)
29 }
30 }
31 }
32 }
33 }
34 strategy {
35 defaultBranchPropertyStrategy {
36 props {
37 }
38 }
39 }
40 }
41 }
42 triggers {
43 periodic(5)
44 }
45 orphanedItemStrategy {
46 discardOldItems {
47 // numToKeep(20)
48 }
49 }
50 if (component.jenkinsfile) {
51 factory {
52 workflowBranchProjectFactory {
53 scriptPath(component.jenkinsfile)
54 }
55 }
56 }
57 }

icinga2 - where to change client monitoring commands?

system ubuntu 16.04
On master node where icinga2 is installed
#ls /etc/icinga2/repository.d/hosts/WIN-U52321E0BAK/
disk C%3A.conf disk.conf icinga.conf load.conf ping4.conf
ping6.conf procs.conf swap.conf users.conf
All conf files have save "dummy" check_command on them for example
#cat load.conf
object Service "load" {
import "satellite-service"
check_command = "dummy"
host_name = "WIN-U52321E0BAK"
zone = "WIN-U52321E0BAK"
}
I cant understand from where dummy command is called and how to customize the checks for warning and critical threshold
The dummy command is defined in /usr/share/icinga2/include/command-plugins.conf, like so:
144 object CheckCommand "dummy" {
145 import "plugin-check-command"
146
147 command = [
148 PluginDir + "/check_dummy",
149 "$dummy_state$",
150 "$dummy_text$"
151 ]
152
153 vars.dummy_state = 0
154 vars.dummy_text = "Check was successful."
155 }
In order to modify the warn and crit levels, you set the custom variable at the host or service level. Using the example of ping, we see the default configuration in that same file:
36 template CheckCommand "ping-common" {
37 import "plugin-check-command"
38
39 command = [ PluginDir + "/check_ping" ]
40
41 arguments = {
42 "-H" = "$ping_address$"
43 "-w" = "$ping_wrta$,$ping_wpl$%"
44 "-c" = "$ping_crta$,$ping_cpl$%"
45 "-p" = "$ping_packets$"
46 "-t" = "$ping_timeout$"
47 }
48
49 vars.ping_wrta = 100
50 vars.ping_wpl = 5
51 vars.ping_crta = 200
52 vars.ping_cpl = 15
53 }
Here's the important bit:
49 vars.ping_wrta = 100
50 vars.ping_wpl = 5
51 vars.ping_crta = 200
52 vars.ping_cpl = 15
So: we go to our host or service definition, thusly (using /etc/icinga2/conf.d/host.conf and the NodeName/localhost definition which everybody has; comments removed):
18 object Host NodeName {
20 import "generic-host"
21
23 address = "127.0.0.1"
24 address6 = "::1"
25
27 vars.os = "Linux"
30 vars.http_vhosts["http"] = {
31 http_uri = "/"
32 }
37
39 vars.disks["disk"] = {
41 }
42 vars.disks["disk /"] = {
43 disk_partitions = "/"
44 }
45 }
And we insert before line 45 above to produce:
18 object Host NodeName {
20 import "generic-host"
21
23 address = "127.0.0.1"
24 address6 = "::1"
25
27 vars.os = "Linux"
30 vars.http_vhosts["http"] = {
31 http_uri = "/"
32 }
37
39 vars.disks["disk"] = {
41 }
42 vars.disks["disk /"] = {
43 disk_partitions = "/"
44 }
45 vars.ping_wrta = 50
46 vars.ping_wpl = 3
47 vars.ping_crta = 10
48 vars.ping_cpl = 2
49 }
...and you have successfully customized the check threshold. You can add those variables to a template or even a hostgroup (I think; better test that, I may be wrong).

Watch app starts with error clientIdentifier for interfaceControllerID not found

I'm having a smartwatch app on watchos2. The app always worked but now when it starts I immediately get this error:
Lop_WatchKit_Extension[17535:7854201] *********** ERROR -[SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier for interfaceControllerID:447E0002 not found
I found some topics here on stackoverflow but nothing solved the problem.
In my case, this was due to a retain cycle in one InterfaceController of mine.
If you get the logs similar to:
[default] -[SPRemoteInterface
_interfaceControllerClientIDForControllerID:]:0000: ComF: clientIdentifier for interfaceControllerID:XXXXXXXX not found
&/or...
[default] _SendRecordedValues:000: ComF:<-Plugin controller ID
XXXXXXXX has no client identifier
First, figure out which InterfaceController has the controller ID XXXXXXXX.
Have this in awake(withContext:)
override func awake(withContext context: Any?) {
//...
if let id = self.value(forKey: "_viewControllerID") as? NSString {
let strClassDescription = String(describing: self)
print("\(strClassDescription) has the Interface Controller ID \(id)")
}
//...
}
This logs:
[Target.Classname: 0xYYYYYYYY] has the Interface Controller ID
XXXXXXXX
Once you identify the InterfaceController causing these logs, you can continue to debug.
It could be different in your case but in mine I had created a retain cycle with self in one of my closures within which took awhile to locate but I eventually broke the retain cycle with a [weak self] capture.
Basically, the error logs appear when an InterfaceController is trying to execute some code but it has already been released.
What I already had:
DispatchQueue.main.async {
self.doSomethingThatDoesSomethingAsync()
}
What I fixed:
DispatchQueue.main.async { [weak self] in
self?.doSomethingThatDoesSomethingAsync()
}
If you use didSet on any IBOutlets it will also throw this error in the logs.
class MyInterfaceController: WKInterfaceController {
#IBOutlet var myLabel: WKInterfaceLabel! {
didSet {
myLabel.setTitle("Test")
}
}
How #nickromano sad, it's happens when you use didSet with IBOutlets. Cause it's calls before awake(withContext context: Any?)
We can suppress this error if wrap it in DispatchQueue.main.async
#IBOutlet var statusLabel: WKInterfaceLabel! {
didSet {
DispatchQueue.main.async {
self.statusLabel.setHidden(true)
}
}
This has happened to me a few times and more times than not, it is because of a timer that is still firing in a just-previously dismissed WKInterfaceController that I did not catch.
Best thing to do aside from comparing ID's like in #staticVoidMan's answer is to read the call stack. In my case I was able to identify that the old timer was still firing based off these hints:
8 Foundation 0x00007fff214be867 __NSFireTimer + 67
9 CoreFoundation 0x00007fff207a8e3f __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
10 CoreFoundation 0x00007fff207a8912 __CFRunLoopDoTimer + 926
Here is the original call stack (for reference):
<MyApp.InterfaceController: 0x7fb3e4d2d020> has the Interface Controller ID 1EB00002
2021-05-26 14:44:06.632758-0600 MyApp WatchKit Extension[73392:3546879] [default] -[SPRemoteInterface _interfaceControllerClientIDForControllerID:]:2464: ComF: clientIdentifier for interfaceControllerID:1EB00007 not found. callStack:(
0 WatchKit 0x00007fff38d1a268 -[SPRemoteInterface _interfaceControllerClientIDForControllerID:] + 220
1 WatchKit 0x00007fff38d1bfff __54+[SPRemoteInterface setController:key:property:value:]_block_invoke + 340
2 WatchKit 0x00007fff38d12323 spUtils_dispatchAsyncToMainThread + 30
3 WatchKit 0x00007fff38d1be60 +[SPRemoteInterface setController:key:property:value:] + 179
4 WatchKit 0x00007fff38d057af -[WKInterfaceObject _sendValueChanged:forProperty:] + 706
5 WatchKit 0x00007fff38d2a5f8 -[WKInterfaceObject _setImage:forProperty:] + 50
6 MyApp WatchKit Extension 0x000000010955531d $s26MyApp_WatchKit_Extension25ActivityIndicatorDelegateC06handleE5TimeryyF + 813
7 MyApp WatchKit Extension 0x000000010955537a $s26MyApp_WatchKit_Extension25ActivityIndicatorDelegateC06handleE5TimeryyFTo + 42
8 Foundation 0x00007fff214be867 __NSFireTimer + 67
9 CoreFoundation 0x00007fff207a8e3f __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
10 CoreFoundation 0x00007fff207a8912 __CFRunLoopDoTimer + 926
11 CoreFoundation 0x00007fff207a7ec5 __CFRunLoopDoTimers + 265
12 CoreFoundation 0x00007fff207a2546 __CFRunLoopRun + 1949
13 CoreFoundation 0x00007fff207a18be CFRunLoopRunSpecific + 567
14 GraphicsServices 0x00007fff25b49fd3 GSEventRunModal + 139
15 UIKitCore 0x00007fff43290f24 -[UIApplication _run] + 917
16 UIKitCore 0x00007fff43295c0b UIApplicationMain + 101
17 WatchKit 0x00007fff38d0de65 WKExtensionMain + 800
18 libdyld.dylib 0x00007fff20202db5 start + 1
19 ??? 0x0000000000000001 0x0 + 1
)
Have you changed the name of your module? If this is the case then you have to go through your storyboard and update it manually for all the Interfaces you have.
Edit with steps to fix:
Go to the storyboard and for each interface open the Identity inspector, then delete what's in Module and press enter, the new module should get auto-filled.

how do i loop numbers around a calendar in c++?

I have been working on this program for hours and cannot find out how to make the numbers loop around after they hit saturday. They either go way passed it to the right or if i add and endl; they go up and down.
// This is how my output looks like (except they curve around they just go forever to the right:
Number of days: 31
Offset: 0
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
This what you mean?
#include <iostream>
using namespace std;
int main()
{
int i;
for (i=1; i<=31; i++) {
cout << ((i<10) ? " " : "") << i << " ";
if (i%7==0) cout << endl;
}
return 0;
}
Outputs:
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
The % sign is the modulus operator. It gives the remainder of division. So every 7th day divided by 7 is going to have a remainder of zero. That's how you check where to put the line breaks.

Remote Connection like Browser Toolbox

I'm trying to interact with another open profile, which is a seperate process. Browser Toolbox does this. I was wondering how can I re-simulate this behavior? Without the prompt asking for "allow remote connection"?
My goal is to (1) find all open firefox process, (2) access each of its xpcom and figure out the profile name, (3) and if its a profile name Im interested in, Ill focus its most recent window.
I don't know but I'm getting somewhere by tracing it in MXR:
http://mxr.mozilla.org/mozilla-release/source/browser/devtools/framework/toolbox-process-window.js#11
11 let { debuggerSocketConnect, DebuggerClient } =
12 Cu.import("resource://gre/modules/devtools/dbg-client.jsm", {});
13 let { ViewHelpers } =
14 Cu.import("resource:///modules/devtools/ViewHelpers.jsm", {});
15
16 /**
17 * Shortcuts for accessing various debugger preferences.
18 */
19 let Prefs = new ViewHelpers.Prefs("devtools.debugger", {
20 chromeDebuggingHost: ["Char", "chrome-debugging-host"],
21 chromeDebuggingPort: ["Int", "chrome-debugging-port"]
22 });
23
24 let gToolbox, gClient;
25
26 function connect() {
27 window.removeEventListener("load", connect);
28 // Initiate the connection
29 let transport = debuggerSocketConnect(
30 Prefs.chromeDebuggingHost,
31 Prefs.chromeDebuggingPort
32 );
33 gClient = new DebuggerClient(transport);
34 gClient.connect(() => {
35 let addonID = getParameterByName("addonID");
36
37 if (addonID) {
38 gClient.listAddons(({addons}) => {
39 let addonActor = addons.filter(addon => addon.id === addonID).pop();
40 openToolbox({ addonActor: addonActor.actor, title: addonActor.name });
41 });
42 } else {
43 gClient.listTabs(openToolbox);
44 }
45 });
46 }
47
I ran the profile and it looks like the pref ..-host is localhost and ..-port is 6080. I'm not sure how this helps target a specific profile though. Maybe on start of the browser toolbox it opened port 6080 to the opener profile. I'm not sure, but if its true, then you'll have to run code from within the target profile to open a port maybe.
Totally not sure though.
But port is opened here:
http://mxr.mozilla.org/mozilla-release/source/browser/devtools/framework/ToolboxProcess.jsm#107
106
107 BrowserToolboxProcess.prototype = {
108 /**
109 * Initializes the debugger server.
110 */
111 _initServer: function() {
112 dumpn("Initializing the chrome toolbox server.");
113
114 if (!this.loader) {
115 // Create a separate loader instance, so that we can be sure to receive a
116 // separate instance of the DebuggingServer from the rest of the devtools.
117 // This allows us to safely use the tools against even the actors and
118 // DebuggingServer itself, especially since we can mark this loader as
119 // invisible to the debugger (unlike the usual loader settings).
120 this.loader = new DevToolsLoader();
121 this.loader.invisibleToDebugger = true;
122 this.loader.main("devtools/server/main");
123 this.debuggerServer = this.loader.DebuggerServer;
124 dumpn("Created a separate loader instance for the DebuggerServer.");
125
126 // Forward interesting events.
127 this.debuggerServer.on("connectionchange", this.emit.bind(this));
128 }
129
130 if (!this.debuggerServer.initialized) {
131 this.debuggerServer.init();
132 this.debuggerServer.addBrowserActors();
133 dumpn("initialized and added the browser actors for the DebuggerServer.");
134 }
135
136 this.debuggerServer.openListener(Prefs.chromeDebuggingPort);
137
138 dumpn("Finished initializing the chrome toolbox server.");
139 dumpn("Started listening on port: " + Prefs.chromeDebuggingPort);
140 },
141

Resources