Java Script assistance

I will be the first to admit I dont know much about if any about JAVA. Attached is the code I am using on a button.

[code]y=0
z=0
#from ftplib import FTP
import sys
import fpmi

sys.add_package(“org.python.core”)

from java.lang import Runnable,Thread
machines = fpmi.db.runQuery(“SELECT mach_num FROM progmode1 WHERE online = 0 and mach_num<10 order by mach_num”)
y = len(machines)
fpmi.tag.writeToTag("[]availrec",y)

#machines = fpmi.db.runQuery(“SELECT mach_num FROM interim WHERE mach_sel = 1 AND shift = 1”)
#machines = event.source.parent.machine
class FTPDownload(Runnable):

def __init__(self):
	self.m=[]

def addMachine(self, machineId):
	self.m.append(machineId)

def run(self):
	for i in self.m:
		k=i+10
		
	
		string = '10.0.0.'+str(k)
		filename = 'setup.csv'
		filename2 = 'emp2.csv'
		try:
			print "Connecting to %s"%string
  [b]1.  ------>[/b]				
			from ftplib import FTP
			ftp = FTP(string)
			print "Connected to %s, Logging in..."%string
			ftp.login('david','bigbrother')


			print "Uploading to %s"%string
			ftp.set_pasv(0)
			ftp.delete(filename)
			ftp.delete(filename2)
			file = open(filename, 'rb')
			print string,filename
			ftp.storbinary('STOR '+filename,file)
			file.close()
			file2 = open(filename2, 'rb')
			print string,filename2
			ftp.storbinary('STOR '+filename2,file2)
			file2.close()
			ftp.quit()
			
			print "Done ",i
		except Exception, e:
			print "HEY STUPID LOOK HERE IT FAILED. HERE IS WHY: %s. ("%string,e,")"
			z=z+1

2. ------> fpmi.tag.writeToTag("[]fault",z)

Create 5 download objects

downloaders = []
for x in range(4):
downloaders.append(FTPDownload())

fpmi.tag.writeToTag("[]wroterec",x)

Round-robin assign machine ids to the downloaders

x=0
for row in machines:
m = row[0]
downloaders[x].addMachine(m)
x = (x+1)%len(downloaders)

Start a thread for each of the 5 downloaders

for downloader in downloaders:
Thread(downloader).start()
[/code]

What I am trying to do is have a self incrementing counter for each time it successfully connect and one for each time it faults. If you look at #1 above I had the following lines:

p=p+1
fpmi.tag.writeToTag("[]wrote",p)

But it kept comming up with NAME ERROR: P error message. I did try different letter but all came back with same error message. I get the same type of message but with the letter Z if an error occurs.

In the section CREATE 5 Downloader objects I tried placing:

fpmi.tag.writeToTag("[]wrote",x)

Here I got a value back but it appears that it only loops thru this routine 3 times.

So where can I place these incremental counters so that they will work properly in this script? Like I said I want the one to count each time there has been success logging into a ftp and one to count each time there has been a failure and then I want to be able to use these on my screen to display.

The error you’re getting is because a line like this:
z=z+1
isn’t going to work because “z” hasn’t been defined. Hence the NameError.
Maybe try:

fpmi.tag.writeToTag("[]fault", fpmi.tag.getTagValue("[]fault")+1)

May I ask where you might place this line of code? I have tried it after the print"CONNECTING TO" and it only counts to 2. I have tried it in the #Create 5 Download objects and it counts to 3. I have tried it in the ROUND ROBIN and START Thread and it counts to 4.

I would have thought by placing it around the CONNECTING TO print that each time it printed that statement it would increment the counter by 1. But that does not seem to be the case.

[quote=“Carl.Gould”]The error you’re getting is because a line like this:
z=z+1
isn’t going to work because “z” hasn’t been defined. Hence the NameError.
Maybe try:

fpmi.tag.writeToTag("[]fault", fpmi.tag.getTagValue("[]fault")+1)

It is executing the increment statement the correct number of times, but due to the way you’re executing this simultaneously on multiple threads, the increment call isn’t thread safe and you’re creating a race condition, which is probably why the count is lower than you’d think.

You’re either going to need to just run all of the downloaders in sequence in one thread, or add thread-safetey via a mutex.

I must be thinking of things incorrectly then. I had made the assumption that since the PRINT function was being printed the correct number of times to the console, that it was looping thru that routine that number of times. So in thought if I counted the number of loops I would get a correct answer.

So can I assume that the console is slight bit different and because of these threads the system open them up at the same time, now the console sees this and prints the correct number of times but any scripting would not see it because the number of threads being opened. Hopefully that is clear because it is slightly confusing to me.

So anyway you mentions a mutex, I am going to google that and see what I can find out. I would appreciate your input as well.

Thanks and have a great day.

[quote=“Carl.Gould”]It is executing the increment statement the correct number of times, but due to the way you’re executing this simultaneously on multiple threads, the increment call isn’t thread safe and you’re creating a race condition, which is probably why the count is lower than you’d think.

You’re either going to need to just run all of the downloaders in sequence in one thread, or add thread-safetey via a mutex.[/quote]

Indeed, as I would expect it to be... you're basically trying to hack together some functionality into code that's rather complex, in a situation that is FAR outside of how FactoryPMI is intended to be used. It's nice that it can do this, but it's important to note that once you leave the groomed trail you'll quickly enter territory that can be difficult to navigate...

Anyhow, I'm not trying to lecture, but only say that you shouldn't be surprised that it's a bit confusing. And in fact, the proper way to do what you want is a bit more involved than just throwing a line here or there. However, I think Carl's working on a write up about that, so I'll leave it to him....

This is probably confusing because it hinges on a very technical software phenomenon called a race condition. The loop is executing the correct number of times, and the increment call is being called the same number of times. But the final number may end up being lower.

Let me try to explain.

You’re running these “downloaders” in multiple threads, simultaneously. So think about this line of pseudocode:

setTagValue(getTagValue + 1)

If you have two threads running this at the same time, they’ll both run the “getTagValue” part, and both get a “2”, lets say. Then they’ll add 1, getting “3”, and they’ll both write that 3 back to the tag. So two threads have “incremented” the tag, but it only went up by one.

Ok, now how to we work around this? There are lots of ways. I recommend encapsulating the counts into a thread-safe class that use something like a Semaphore as a mutex like this:

[code]#from ftplib import FTP
import sys
import fpmi

sys.add_package(“org.python.core”)

from java.lang import Runnable,Thread
machines = fpmi.db.runQuery(“SELECT mach_num FROM progmode1 WHERE online = 0 and mach_num<10 order by mach_num”)

fpmi.tag.writeToTag("[]availrec",len(machines))
fpmi.tag.writeToTag("[]fault", 0)
fpmi.tag.writeToTag("[]wroterec", 0)

class Counter:
def init(self):
from java.util.concurrent import Semaphore
self.goodCount=0
self.badCount=0
self.mutex=Semaphore(1) # this is for multithreading support

def incrementGood():
	import fpmi
	self.mutex.aquire()
	self.goodCount += 1
	fpmi.tag.writeToTag("[]wroterec", self.goodCount)
	self.mutex.release()

def incrementBad():
	import fpmi
	self.mutex.aquire()
	self.badCount += 1
	fpmi.tag.writeToTag("[]fault", self.badCount)
	self.mutex.release()

#machines = fpmi.db.runQuery(“SELECT mach_num FROM interim WHERE mach_sel = 1 AND shift = 1”)
#machines = event.source.parent.machine
class FTPDownload(Runnable):

def __init__(self, counter):
	self.m=[]
	self.counter=counter

def addMachine(self, machineId):
	self.m.append(machineId)

def run(self):
	for i in self.m:
		k=i+10
		
	
		string = '10.0.0.'+str(k)
		filename = 'setup.csv'
		filename2 = 'emp2.csv'
		try:
			print "Connecting to %s"%string			 
			from ftplib import FTP
			ftp = FTP(string)
			print "Connected to %s, Logging in..."%string
			ftp.login('david','bigbrother')


			print "Uploading to %s"%string
			ftp.set_pasv(0)
			ftp.delete(filename)
			ftp.delete(filename2)
			file = open(filename, 'rb')
			print string,filename
			ftp.storbinary('STOR '+filename,file)
			file.close()
			file2 = open(filename2, 'rb')
			print string,filename2
			ftp.storbinary('STOR '+filename2,file2)
			file2.close()
			ftp.quit()
			
			print "Done ",i
			self.counter.incrementGood()
		except Exception, e:
			print "HEY STUPID LOOK HERE IT FAILED. HERE IS WHY: %s. ("%string,e,")"
			self.counter.incrementBad()

Create 5 download objects

counter = Counter()
downloaders = []
for x in range(4):
downloaders.append(FTPDownload(counter))

Round-robin assign machine ids to the downloaders

x=0
for row in machines:
m = row[0]
downloaders[x].addMachine(m)
x = (x+1)%len(downloaders)

Start a thread for each of the 5 downloaders

for downloader in downloaders:
Thread(downloader).start()[/code]

I have copied and pasted and also typed in the script as shown. However I keep getting the same error message and I wondering if it is because I am running an older version of FPMI or if I am missing something I can not see from this end.

The error message occurs when ever it tries to run the incrementGOOD() or incrementBAD(). The error message is:

TypeError: incrementGood() too many arguments; expected 0 got 1

I thought maybe it had something to do with the call to FPMI so I remarked those out and it still came up with the same error.

Sorry, replace the folling two lines in the script like so:

def incrementGood(): def incrementBad():

becomes

def incrementGood(self): def incrementBad(self):

Well that solved one problem, now a new one has come up. This one is:

File “event:actionPerformed”, line 80, in run
File “event:actionPerformed”, line 30, in incrementBad
AttributeError: aquire

I did so a search on Semephore, Mutex and this web page

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Semaphore.html

Shows that the acquire and release are used in the semephore/mutex. So why would it complain that its not a valid attribute??

:frowning: because I spelled it wrong. Oops!

it’s “acquire” not “aquire”

Make the appropriate changes…