I need help in applying multi-threading to groovy class - multithreading

I have one groovy class which creates issue but when I need create issue more than 2, I'm facing with performance problems that's why I would like to use threads for better performance.
Here is my code example. Please help me adding multi-threading to this code(I would like to apply mutli-threading to static void main part):
import // some libraries
class NotificationIssue
{
NotificationIssue()
{
//Some codes
}
def getCustomFieldsValues (issueid)
{
//Some codes
}
def Check3cxPhone()
{
//Some codes
}
def CheckNetworkFolder()
{
//Some codes
}
def setIQLFacadeAndObjectFacade()
{
//Some codes
}
def CheckServerSystemAndUserAccount()
{
//Some codes
}
def CheckService()
{
//Some codes
}
def setIssueInputParameter()
{
//Some codes
}
}
public static void main(String[] args)
{
//1st Notification issue for IT
NotificationIssue NotificationForIT = new NotificationIssue()
def key1 = NotificationForIT.getCustomFieldsValues(issue.key)
NotificationForIT.setIQLFacadeAndObjectFacade()
NotificationForIT.Check3cxPhone()
NotificationForIT.CheckNetworkFolder()
NotificationForIT.CheckServerSystemAndUserAccount()
NotificationForIT.CheckService()
NotificationForIT.setIssueInputParameter(customerRtype, "Notification Issue-", issueType, user,"SD",10200)
//2nd Notification for another department
NotificationIssue StampNotification = new NotificationIssue()
def key2 = StampNotification.getCustomFieldsValues(issue.key)
StampNotification.setIQLFacadeAndObjectFacade()
//3rd Notification issue for...
...
}

I did it using thread.start() and thread.join()

Related

How could an object running a thread communicate back to the containing class?

Class Person()
{
Eyes eyes;
Person(){
eyes = new Eyes();
eyes.watching();
}
Thread updateGUI(){
//want to safely report what's being seen
}
}
Class Eyes()
{
String whatIsee;
public void watching()
{
Task task = new Task()
{
while(1)
{
whatIsee = look();
//then send what I see back to Person
}
}
}
}
Could I pass a list of "whatIHaveSeen" into the Eyes constructor. An do it that way. I'm aware work will be needed to make it thread safe. I just want and understanding of how to go about doing it.

How do I get a method and KeyEventArgs interact with each other?

I am trying to learn programming for fun (apologies in advance if I get the terminology wrong) and have found an issue that I am struggling to solve. I have been trying to get a program to interact with key a key being pressed (e.g: you press "space" and the console will print "hello world") and am unable to get the event and method to interact.
What am I doing wrong; is it a simple step I've missed or have I got the structure completely wrong?
Thank you!
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Key_Input_2
{
class MainProgram
{
static void Main(string[] args)
{
KeyInput_2 k = new KeyInput_2();
bool keyType = k.dKey_KeyDown();
if (keyType == true)
{
Console.WriteLine("Hello World");
}
}
}
class KeyInput_2
{
bool dKey = false;
public bool dKey_KeyDown(object sender, KeyEventArgs e)
{
while (dKey == false)
{
if (e.KeyCode == Keys.D)
{
return true;
}
else
{
return false;
}
}
}
}
}
Start with this:
public bool dKey_KeyDown()
{
var key = Console.ReadKey();
if (key == ConsoleKey.D)
{
return true;
}
else
{
return false;
}
}
The code you have posted won't work at all.
First, you are calling dKey_KeyDown without any arguments, but the declaration of this method requires two arguments, object sender, and KeyEventArgs e...so the code won't even compile, let alone run.
Second, it looks like you might have copied and pasted this from some example code from Windows Forms coding; in this case sender and e are supplied by the Forms code as part of its event handling mechanism. I won't go into the details here, but it won't work in a Console application..you can read more about it here
In the interest of helping out, here is a simple program that will do what you want, it uses Console.ReadKey
using System;
namespace SimpleKey
{
class Program
{
static void Main(string[] args)
{
//make a variable to store the input from the user's keypress
ConsoleKeyInfo input = new ConsoleKeyInfo();
//keep executing the code inside the block ({..}) until the user presses the Spacebar
while (input.Key != ConsoleKey.Spacebar)
{
Console.WriteLine("Press SpaceBar...");
input = Console.ReadKey();
}
//now they have pressed spacebar, so display the message
Console.WriteLine("Hello World");
}
}
}
Finally - congratulations on deciding to take up programming! Stick with it, you'll be glad you did :)

Playframework Excel file generation

I've installed excel module in order to generate reports from datas recorded by my application into database.
It works fine : i can create report simply by clicking on a link into my main page and render into excel template.
But i'd rather generate excel file periodically (using a job) and save it into a shared folder, and that without any human action (so not by clicking on a link).
It's like I want to trigger the associated controller to render into my template automatically.
Does anyone got any tips on it for me?
So the problem is you can't pass some parameters into the job, or...?
Using something like this just doesn't work?
#On("0 45 4-23 ? * MON-FRI")
public class ExcelJob extends Job {
public void doJob() {
// generate excel
}
}
I wrote my own Excel generator using JExcel, and I use it for scheduled generation without a problem. It also doesn't require a template, because the report structure is derived from annotations. This is roughly 20 lines of code - you may want to try it for yourself.
This is really rough and lacks good user feedback, but gives you the idea...
Excel generator - not Play-specific in any way
public class ExcelGenerator
{
public void generateReport(Function successCallback,
Function failureCallback)
{
try
{
byte[] report = // generate your report somehow
successCallback.execute(report);
}
catch (Exception e)
{
failureCallback.execute(e.getMessage());
}
}
}
A function interface for callbacks (very basic)
public interface Function
{
public void execute(Object... args);
}
Your Play controller
public class MyController extends Controller
{
public static void index()
{
render();
}
public static void createReport()
{
Function failureCallback = new Function()
{
public void execute(Object... args)
{
flash.error(args[0]);
indxe();
}
};
Function successCallback = new Function()
{
public void execute(Object... args)
{
renderBinary((byte[])args[0]);
}
};
ExcelGenerator excelGenerator = new ExcelGenerator();
excelGenerator.generateReport(successCallback,
failureCallback);
}
}
Finally, re-use the ExcelGenerator from your job
public class MyJob extends Job
{
public void doJob()
{
Function failureCallback = new Function()
{
public void execute(Object... args)
{
Logger.error(args[0]);
}
}
Function successCallback = new Function()
{
public void execute(Object... args)
{
byte[] report = (byte[])args[0];
// write report to disk
}
}
ExcelGenerator excelGenerator = new ExcelGenerator();
excelGenerator.generateReport(successCallback,
failureCallback);
}
}
You'll still need to write your own report generator, or refactor the existing excel module to provide what you need.
So if you want to run and manage several jobs you can do something like this
for (int i = 0; i < 10; i++) {
SendingMessageJob sendingMessageJob = new SendingMessageJob();
promises.add(sendingMessageJob.now());
}
boolean allDone = false;
while (!allDone) {
allDone = true;
for (F.Promise promise : promises) {
if (!promise.isDone()) {
allDone = false;
break;
}
}
}
// when arrive here all jobs have finished their process
You can check the Play documentation, specifically the section on jobs, where you'll see examples on how to create automatically triggered methods. This should solve your issue.
EDIT (update on comment):
You can manually trigger a job, do this:
new MyExcelGeneratorJob().doJob();
Thing is, Play is stateless, so the job should use data from the database. Instead of trying to pass parameters from your request into the Job (won't work) try to store that data in a staging area in the database that the job loads and processes to generate the excel.

How to pass parameters to a CodeActivity in a NativeActivity code sequence

I'm trying to get windows workflows working, and I've become a little stumped.
I've gotten a single workflow working, but now I am trying to do something a little more complex: start a workflow, where each activity itself contains a workflow. (Picture something like the main program starts the activities "Input, logic, and output", and then each of those have additional activities like "prompt user, get input, etc.")
I've had it working fine, with the example from here (http://msdn.microsoft.com/en-us/magazine/gg535667.aspx), when I am not passing any parameters from the main program to the activites. My question is, how exactly does the 'Variables' and 'metadata.SetVariablesCollection' work in the NativeActivity, and how to I get the parameters to the low level activities?
This is what I am currently trying:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.Collections.ObjectModel;
using System.Activities.Statements;
namespace Project1
{
internal class MainProgram
{
internal static void Main(string[] args)
{
try
{
var act = new SimpleSequence();
act.Activities.Add((Activity)(new WriteSomeText()));
act.Activities.Add((Activity)(new WriteSomeText()));
act.Activities.Add((Activity)(new WriteSomeText()));
act.Variables.Add(new Variable<string> ("stringArg", "TEXT"));
WorkflowInvoker.Invoke(act);
}
catch (Exception ex)
{
System.Console.WriteLine("EXCEPTION: {0}", ex);
}
}
public class WriteSomeText : CodeActivity
{
[RequiredArgument]
public InArgument<string> stringArg { get; set; }
protected override void Execute(CodeActivityContext context)
{
string output = context.GetValue(stringArg);
System.Console.WriteLine(output);
}
}
public class SimpleSequence : NativeActivity
{
Collection<Activity> activities;
Collection<Variable> variables;
Variable<int> current = new Variable<int> { Default = 0 };
public Collection<Activity> Activities
{
get
{
if (this.activities == null)
this.activities = new Collection<Activity>();
return this.activities;
}
set
{
this.activities = value;
}
}
public Collection<Variable> Variables
{
get
{
if (this.variables == null)
this.variables = new Collection<Variable>();
return this.variables;
}
set
{
this.variables = value;
}
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
metadata.SetChildrenCollection(this.activities);
metadata.SetVariablesCollection(this.variables);
metadata.AddImplementationVariable(this.current);
}
protected override void Execute(NativeActivityContext context)
{
if (this.Activities.Count > 0)
context.ScheduleActivity(this.Activities[0], onChildComplete);
}
void onChildComplete(NativeActivityContext context, ActivityInstance completed)
{
int currentExecutingActivity = this.current.Get(context);
int next = currentExecutingActivity + 1;
if (next < this.Activities.Count)
{
context.ScheduleActivity(this.Activities[next], this.onChildComplete);
this.current.Set(context, next);
}
}
}
}
}
This ends up throwing the following exception:
EXCEPTION: System.Activities.InvalidWorkflowException: The following errors were encountered while processing the workflow tree:
'WriteSomeText': Value for a required activity argument 'stringArg' was not supplied.
'WriteSomeText': Value for a required activity argument 'stringArg' was not supplied.
'WriteSomeText': Value for a required activity argument 'stringArg' was not supplied.
at System.Activities.Validation.ActivityValidationServices.ThrowIfViolationsExist(IList`1 validationErrors)
at System.Activities.Hosting.WorkflowInstance.ValidateWorkflow(WorkflowInstanceExtensionManager extensionManager)
at System.Activities.Hosting.WorkflowInstance.RegisterExtensionManager(WorkflowInstanceExtensionManager extensionManager)
at System.Activities.WorkflowApplication.EnsureInitialized()
at System.Activities.WorkflowApplication.RunInstance(WorkflowApplication instance)
at System.Activities.WorkflowApplication.Invoke(Activity activity, IDictionary`2 inputs, WorkflowInstanceExtensionManager extensions, TimeSpan timeout)
at System.Activities.WorkflowInvoker.Invoke(Activity workflow, TimeSpan timeout, WorkflowInstanceExtensionManager extensions)
at System.Activities.WorkflowInvoker.Invoke(Activity workflow)
at Project1.MainProgram.Main(String[] args) in c:\users\user\documents\visual studio 2010\Projects\ModelingProject1\Project1\MainProgram.cs:line 25
I know, I only pass 1 parameter, but the exception still says that I am missing 3 parameters. I am missing something as to how to do this properly.
You're correctly declaring stringArg as an InArgument but you're not passing any value to it when calling it inside SimpleSequence.
You can pass something using the constructor, while constructing the all activity itself, like this:
public class WriteSomeText : CodeActivity
{
[RequiredArgument]
public InArgument<string> stringArg { get; set; }
public WriteSomeText(string stringArg)
{
this.stringArg = stringArg;
}
protected override void Execute(CodeActivityContext context
{
string output = context.GetValue(stringArg);
System.Console.WriteLine(output);
}
}
// Calling the activity like this:
internal static void Main(string[] args)
{
var act = new SimpleSequence()
{
Activities =
{
new WriteSomeText("hello"),
new WriteSomeText("world"),
new WriteSomeText("!")
}
};
WorkflowInvoker.Invoke(act);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
Also notice that is a best practice to use the constructor to initialize collections:
public SimpleSequence()
{
activities = new Collection<Activity>();
variables = new Collection<Variable>();
}
This way is even more intuitive to initialize the activity:
var act = new SimpleSequence()
{
Activities =
{
new WriteSomeText("hello"),
new WriteSomeText("world"),
new WriteSomeText("!")
},
Variables =
{
new Variable<int>("myNewIntVar", 10),
// ....
}
};
EDIT:
There are a couple of other ways to approach the problem. This is your best friend while starting in the WF4 world.
Check WF\Basic\CustomActivities\Code-Bodied for a little push with this particular case.

How to build a simple IDE using Groovy?

Following this question Click Here. I thought of creating a simple IDE for groovy and Java. Code is reproduced here for easy reference:
import groovy.swing.SwingBuilder
import java.awt.BorderLayout as BL
import static javax.swing.JFrame.EXIT_ON_CLOSE
import org.fife.ui.rsyntaxtextarea.*
RSyntaxTextArea textArea = new RSyntaxTextArea()
textArea.syntaxEditingStyle = SyntaxConstants.SYNTAX_STYLE_JAVA
swing = new SwingBuilder()
frame = swing.frame(title:"test", defaultCloseOperation:EXIT_ON_CLOSE, size:[600,400], show:true ) {
borderLayout()
panel( constraints:BL.CENTER ) {
borderLayout()
scrollPane( constraints:BL.CENTER ) {
widget textArea
}
}
}
Now I have all the codings entered by the user in textarea which is an Object of RSynataxTextArea, how i should perform compilation for all the code written by the user? Is there any class for this purpose or any ways of doing it in Groovy?
Thanks in advance.
I you look in the src/main/groovy/ui folder of the source download for Groovy, you'll see the code which makes the groovyConsole work
If you look inside the ConsoleSupport class, you'll see the way the console does it:
protected Object evaluate(String text) {
String name = "Script" + counter++;
try {
return getShell().evaluate(text, name);
}
catch (Exception e) {
handleException(text, e);
return null;
}
}
where getShell() is:
public GroovyShell getShell() {
if (shell == null) {
shell = new GroovyShell();
}
return shell;
}
So it returns a new GroovyShell or the exiting one if one already exists

Resources