I have an application running on WebLogic 12.2.1. This application is consisted of JAX-RS web services. I need to create a background thread to periodically clean up files created by the web services. What would be the correct way to do so? I know how to create threads in stand-alone Java programs, but never done it on J2EE applications.
Have a look at the JEE Timer Service http://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html
Sample Implementation:
import javax.ejb.Schedule;
import javax.ejb.Singleton;
#Singleton
public class Timer {
// Triggers every 30 seconds from 6PM till 6AM
#Schedule(second = "*/30", minute = "*", hour = "18-6", dayOfWeek = "*", dayOfMonth = "*", month = "*", year = "*", info = "Timer", persistent = false)
public void produce() {
LOGGER.info("Sending Signal");
// Do Stuff
}
}
Related
I am following the example in the link https://github.com/microsoftgraph/msgraph-training-changenotifications and creating and updating the notification subscription using a timer class.
[HttpGet]
public ActionResult<string> Get()
{
var graphServiceClient = GetGraphClient();
var sub = new Microsoft.Graph.Subscription();
sub.ChangeType = "updated";
sub.NotificationUrl = config.Ngrok + "/api/notifications";
sub.Resource = "/users";
sub.ExpirationDateTime = DateTime.UtcNow.AddMinutes(5);
sub.ClientState = "SecretClientState";
var newSubscription = graphServiceClient
.Subscriptions
.Request()
.AddAsync(sub).Result;
Subscriptions[newSubscription.Id] = newSubscription;
if(subscriptionTimer == null)
{
subscriptionTimer = new Timer(CheckSubscriptions, null, 5000, 15000);
}
return $"Subscribed. Id: {newSubscription.Id}, Expiration: {newSubscription.ExpirationDateTime}";
}
But I have noticed the timer does not always get triggered(eg: network related issue/ after a fresh deployment of the code).
Is there a better way to replace this timer?
I have heard about webjobs in azure, is it possible to replace this timer with azure webjobs? If so can someone point me to some documentation on how?
I noticed you're using ASPNET, if you're using the ASPNETCORE version, since 2.x, you can have background services that you could run every X hours to resubscribe (update) the subscriptions. That's what we're using (and we're on Azure). I would guess webjobs could do the trick, but I have not used them yet. You could also have an external service that calls one of your endpoints every X hours (like a CRON job) .
hope this helps!
JS
I have created a web page where users can upload a file which contains data that are inserted into the Lead table in Microsoft Dynamics CRM 2011.
The weird thing now is that when I deploy to our test environment the application runs fine seemingly but absolutely no rows are imported. In my dev environment it works just fine.
After a while when trying to find the error I created a setting that runs the application without using threading (Thread.Run basically) and then it inserts all the Leads. If I switch back to using threads it inserts no leads at all although I get no application errors.
When using SQL Server Profiler I can see in dev (where it works with threading) that all of the insert statements run. When profiling in test environment no insert statements at all are run.
I sort of get the feeling that there is some server issue or setting that is causing this behaviour but when googling I don't really get any results that have helped me.
I was sort of hoping that someone recognizes this problem. I haven't got much experience in using threading so maybe this is some road bump that I need to go over.
I cannot show my code completely but this is basically how I start the threads:
for (int i = 0; i < _numberOfThreads; i++)
{
MultipleRequestObject mpObject = new MultipleRequestObject() { insertType = insertType, listOfEntities = leadsForInsertionOrUpdate[i].ToList<Entity>() };
Thread thread = new Thread(delegate()
{
insertErrors.AddRange(leadBusinessLogic.SaveToCRMMultipleRequest(mpObject));
});
thread.Start();
activeThreads.Add(thread);
}
// Wait for threads to complete
foreach (Thread t in activeThreads)
t.Join();
I initialize my crm connection like this (it reads the connectionstring from web.config -> connectionstrings)
public CrmConnection connection { get; set; }
private IOrganizationService service { get; set; }
public CrmContext crmContext { get; set; }
public CrmGateway()
{
connection = new CrmConnection("Crm");
service = (IOrganizationService)new OrganizationService(connection);
crmContext = new CrmContext(service);
}
We are writing a test chat application using the Azure service bus backplane. We have stripped it down to barebones but there are pockets of "lag" where messages sent don't get received for up to 15 seconds later.
Startup.cs
string connectionString = GetServiceBusConnectionString();
GlobalHost.DependencyResolver.UseServiceBus(connectionString, "Chat");
app.MapSignalR();
Chathub.cs
protected void MsgAll(User user, string content)
{
Clients.All.broadcastMessage(new Message() { Content = content, NickName = user.NickName, Status = user.Status, TimeStamp = DateTime.Now });
}
Chat.js
self.chat.client.broadcastMessage = function (res) {
self.messages.push(new messageItem(res));
var objDiv = document.getElementById("chat-messages");
objDiv.scrollTop = objDiv.scrollHeight;
};
It works fine when its standalone, but starts lagging intermittently when we add the backplane, even on one server. Any tips/help appreciated.
Additional info:
using defaults
Looking at mgmt portal we see 5 topics created
I've been using Autoscale to shift between 2 and 1 instances of a cloud service in a bid to reduce costs. This mostly works except that from time to time (not sure what the pattern seems to be here), the act of scaling up (1->2) causes both instances to recycle, generating a service outage for users.
Assuming nothing fancy is going on in RoleEntry in response to topology changes, why would scaling from 1->2 restart the already running instance?
Additional notes:
It's clear both instances are recycling by looking at the Instances
tab in Management Portal. Outage can also be confirmed by hitting the
public site.
It doesn't happen consistently but I'm not sure what the pattern is. It feels like when the 1-instance configuration has been running for multiple days, attempts to scale up recycle both. But if the 1-instance configuration has only been running for a few hours, you can scale up and down without outages.
The first instance always comes back much faster than the 2nd instance being introduced.
This has always been this way. When you have 1 server running and you go to 2+, the initial server is restarted. In order to have a full SLA, you need to have 2+ servers at all time.
Nariman, see my comment on Brent's post for some information about what is happening. You should be able to resolve this with the following code:
public class WebRole : RoleEntryPoint
{
public override bool OnStart()
{
// For information on handling configuration changes
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
IPHostEntry ipEntry = Dns.GetHostEntry(Dns.GetHostName());
string ip = null;
foreach (IPAddress ipaddress in ipEntry.AddressList)
{
if (ipaddress.AddressFamily.ToString() == "InterNetwork")
{
ip = ipaddress.ToString();
}
}
string urlToPing = "http://" + ip;
HttpWebRequest req = HttpWebRequest.Create(urlToPing) as HttpWebRequest;
WebResponse resp = req.GetResponse();
return base.OnStart();
}
}
You should be able to control this behavior. In the roleEntrypoint, there's an event you can trap for, RoleEnvironmentChanging.
A shell of some code to put into your solution will look like...
RoleEnvironment.Changing += RoleEnvironmentChanging;
private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
{
}
RoleEnvironment.Changed += RoleEnvironmentChanged;
private void RoleEnvironmentChanged(object sender, RoleEnvironmentChangedEventArgs e)
{
}
Then, inside the RoleEnvironmentChanged method, we can detect what the change is and tell Azure if we want to restart or not.
if ((e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange)))
{
e.Cancel = true; // don't recycle the role
}
I'm working on CXF client services but load test (1000 concurrent users) leads to lot's of locked threads and JVM crash. The threads seems to be locked on the Jaxb class AccessorInjector :
com/sun/xml/bind/v2/runtime/reflect/opt/AccessorInjector#341F3D78/341F3D84
My client is a singleton which is called by a servlet. The client calls the webservice like that :
HttpServlet :
SRecherche srech = SRecherche .getInstance();
String reponse = srech.recherche(parametres, retour);
Client Service :
public static SRecherche getInstance() {
synchronized (SRecherche .class) {
if (instance == null) {
instance = new SRecherche();
}
}
return instance;
}
.
.
.
.
public String recherche(String parametres, String retour[]) {
SampleSOAPService sampleSOAPService = new SampleSOAPService(ClassLoader.getSystemResource("service.wsdl"));
SampleSOAP s = sampleSOAPService .getService();
((BindingProvider) s).getRequestContext().put("thread.local.request.context", "true");
// set the username and password
((BindingProvider) s).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, username);
((BindingProvider) s).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);
//set timeout to be longer
Client client = ClientProxy.getClient(s);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(timeout);
httpClientPolicy.setAllowChunking(false);
httpClientPolicy.setReceiveTimeout(timeout);
httpClientPolicy.setConnection(ConnectionType.CLOSE);
http.setClient(httpClientPolicy);
.
.
.
s.callService(...);
.
.
}
I'm working on weblogic 9.2/Java 5.0/CXF 2.5
Do you have any idea about how lot's of simultaneous call of that client may lead to locked threads ?
JDK Version :
J2RE 5.0 IBM J9 2.3 AIX ppc-32 build j9vmap3223-20081129
JVM Parameters :
-Xjcl:jclscar_23
-Dcom.ibm.oti.vm.bootstrap.library.path=/usr/java5/jre/bin
-Dsun.boot.library.path=/usr/java5/jre/bin
-Djava.library.path=/usr/java5/jre/bin:/usr/java5/jre/bin:/usr/java5/jre/bin/classic:/usr/java5/jre/bin:/exec/products/weblogic/v9.2/bea/patch_weblogic921/profiles/default/native:/exec/products/weblogic/v9.2/server/native/aix/ppc:/usr/java5/jre/bin/j9vm:/usr/lib
-Djava.home=/usr/java5/jre
-Djava.ext.dirs=/usr/java5/jre/lib/ext
-Duser.dir=/exec/products/weblogic/v9.2/user_projects/domains/rforce
_j2se_j9=70912 0xF12ACF08
vfprintf 0x300017A4
-Xms2048m
-Xmx2048m
-Dcom.sun.xml.namespace.QName.useCompatibleSerialVersionUID=1.0
-da
-Dplatform.home=/exec/products/weblogic/v9.2
-Dwls.home=/exec/products/weblogic/v9.2/server
-Dwli.home=/exec/products/weblogic/v9.2/integration
-Dweblogic.management.discover=true
-Dwlw.iterativeDev=false
-Dwlw.testConsole=false
-Dwlw.logErrorsToConsole=
-Dweblogic.ext.dirs=/exec/products/weblogic/v9.2/bea/patch_weblogic921/profiles/default/sysext_manifest_classpath
-Dcom.wily.introscope.agentProfile=/exec/products/weblogic/introscope/wily/IntroscopeAgent_prod.profile
-javaagent:/exec/products/weblogic/introscope/wily/Agent.jar
-Dcom.wily.introscope.agent.agentName=RFORCE
-Dweblogic.Name=RForceServer
-Djava.security.policy=/exec/products/weblogic/v9.2/server/lib/weblogic.policy
-Dinvokedviajava
-Djava.class.path=/exec/products/weblogic/v9.2/server/lib/geronimo-ws-metadata_2.0_spec-1.1.3.jar:/exec/products/weblogic/v9.2/user_projects/domains/rforce/config/rforce/:/exec/products/weblogic/v9.2/user_projects/domains/rforce/config/rforce/wsdl/drakkar/:/usr/java5/lib/tools.jar:/exec/products/weblogic/v9.2/server/lib/weblogic_sp.jar:/exec/products/weblogic/v9.2/server/lib/weblogic.jar:/exec/products/weblogic/v9.2/server/lib/webservices.jar::/exec/products/weblogic/v9.2/common/eval/pointbase/lib/pbclient51.jar:/exec/products/weblogic/v9.2/server/lib/xqrl.jar::
vfprintf
_port_library 0xF12AC748
-Xdump
Thanks,
Simon
Just from a quick glance, since you are doing pretty much everything manually (i.e. handling all the connections, etc.) about the only thing I could recommend would be to start a threqad in your public String recherche(String parametres, String retour[]) implementation.
Wrap all the code you have there in an anonymous runnable or Thread instance and kick it off. The thread will handle all the processing and response to client, leaving the recherche() method free to take another call.
Just a thought.
Also in the way of FYI, the client in what you describe above would actually be the Servlet, as it is making the call to the service. Or in other words, it looks like the Servlet is the consumer and the singleton is the provider.