Gå til innhold

Trigge program ved oppdatering av MySQL?


Anbefalte innlegg

Jeg har et c++ program som jeg ønsker skal kjøre når en ny rad blir lagt til i MySQL-tabellen, men problemet er at jeg ikke vet hvordan programmet kan få vite at det har kommet en ny linje i tabellen. Er det noen som vet? Jeg vet hvordan man kan bruke c++ til å få informasjon fra mysql, men jeg ønsker ikke å sende nettverkstrafikk hvert sekund for å se om det har kommet en ny rad.

Lenke til kommentar
Videoannonse
Annonse

Om programmet ligger på SQL-server kan du lage en trigger i mysql, hvor du bruker sys_exec() for å starte opp programmet.

 

Om det du ønsker å gjøre bare er å oppdatere / endre database-informasjon i programmet hver gang det kommer en ny rad, så kan du bare la triggeren gjøre de tingene for deg.

 

Edit: Det kan være du trengr UDF-plugin til MySQL for å gjøre dette.

Endret av etse
Lenke til kommentar

Ja, ligger på samme server foreløpig, men planen er muligens og flytte MySQL-databasen til en annen pc.

 

En bruker skal via en webside opprette en rad i tabellen.

Når dette skjer skal et program kjøre, noe som kan ta litt tid (sende noe data over seriell-kabel, og motta svar). Når svar er mottatt vil c++ programmet oppdatere svaret til den eksisterende raden i tabellen.

 

Så, jeg antar jeg må ha dette programmet i tillegg til triggeren.

 

Skal se litt mer på sys_exec(), så kommer jeg tilbake. Takk så langt!

Endret av r2d290
Lenke til kommentar

En mulighet om de er på ulike servere er at sys_exec() starter en script som gir beskjed videre til maskinen der programmet kjører og ber det starte.

 

Men hvorfor kan du ikke bruke polling? Ser du skriver du ikke vil sende nettverkstrafikk, men det er jo snakk om veldig lite data her. Noen spesiell grunn til at du er redd for den lille ekstra trafikken? Den vil jo være nesten neglisjerbar når man ser på skalerbarheten på serveren. La scriptet ditt polle noen ganger i minuttet etter oppdateringer, vil jo være minimalt med ressursbruk her.

Endret av etse
Lenke til kommentar

Vel, poenget/problemet er at det eksterne programmet må kjøres relativt ofte. Det er 50 klienter som i løpet av en time hvert minutt (50*60=3000 oppdateringer på en time) skal individuelt først opprette en ny rad, for så å få det eksterne programmet til å oppdatere hver av disse radene if FIFO-rekkefølge. Dette tror jeg innebærer en ganske vesentlig nettverkstrafikk. Det er ok i de to timene dette foregår i løpet av en skoledag, men det blir litt voldsomt hvis den skal lukte etter endringer 3000 ganger/time døgnet rundt.

 

Eller finnes det en mer fornuftig måte å gjøre dette på?

Lenke til kommentar

du må ikke være redd for å gjøre enkle request til en SQL-database. Det første er f.eks. hva store krav har du til responstid? Må du starte å kjøre programmet med en gang? Kan det vente et par sekunder? Om kjøretiden på programmet er litt lang (flere sekunder) så er det i hvertfall ikke et problem.

 

La programmet sende en spørring til SQL serveren hvor den spør etter alle nye rader, hvor du sorterer de i den rekkefølgen du ønsker å behandle de. (FIFO kan lett ordnes ved å sortere på ID). La programmet ditt fungere på cirka følgende måte: (psaudo-pythonkode eksempel)

while True: # do forever
    newRows = getNewRowsFromSQLServer();
    if numElements(newRows) is 0:
        sleep(1 second)
        continue
 
    for row in newRows:
        newData = computeDataBasedOnRow(row)
        updateDataOnSQLServer(newData)   

Denne vil ikke belaste serveren og trafikken din noe nevneverdig. Og du kan bare korte ned sleepen om du vil gjøre den mer responsiv. I tillegg har den fordel med at den laster ned flere rader i bulk - så om mange nye rader har kommet slipper du å gjøre mange tilkoblinger for dette.

 

Du må huske at de gangene du ikke får noe ny data, har det gått veldig lite nettverkstrafikk. Det å sende en request for å få et tomt svar tilbake igjen koster nesten ingenting. Og med mindre tabellen på serveren og/eller du ikke har et helt på tryne oppsett av serveren så vil det å gjøre oppslag etter nye rader gå veldig fort.

 

Dataen som oftest må sendes er jo selve informasjonen i radene, men den må du jo overføre uansett hvilken fremgangsmåte du velger.

  • Liker 1
Lenke til kommentar

Takk for gode innspill begge to!

 

quantum: Det er PHP-script som legger inn de nye radene. Kan PHP få et program til å kjøre (internt eller eksternt) når en bruker trykker på "Submit"?

 

du kan og gjøre rest-kall om programmet kjører på en annen server via PHP med bruk av "file_get_contents()".

 

men igjen, jeg ser ikke hvorfor du er redd for å få litt nettverkstrafikk. mengden data ved polling er minimal og vil nesten ikke påvirke deg uansett.

 

Men en annen ting, hvorfor vil du legge ting som en rad inn i en database for så å laste raden ned og oppdatere den i et program senere? Hvorfor ikke bare sende dataen direkte til dette programmet som behandler dataen, som så bare putter inn korrekt data inn i databasen når den er ferdig med databehandlingen?

Lenke til kommentar

Men en annen ting, hvorfor vil du legge ting som en rad inn i en database for så å laste raden ned og oppdatere den i et program senere? Hvorfor ikke bare sende dataen direkte til dette programmet som behandler dataen, som så bare putter inn korrekt data inn i databasen når den er ferdig med databehandlingen?

 

 

Det høres ut som et enda bedre forslag ja. Uten å vite hva vi egentlig prøver å lage her ...

 

Polling vil også virke, men spesielt elegant er det ikke.

Lenke til kommentar

Men en annen ting, hvorfor vil du legge ting som en rad inn i en database for så å laste raden ned og oppdatere den i et program senere? Hvorfor ikke bare sende dataen direkte til dette programmet som behandler dataen, som så bare putter inn korrekt data inn i databasen når den er ferdig med databehandlingen?

 

Må du slutte å stille så mange gode spørsmål. Det innebærer en utfordring dog. Raden som jeg idag oppretter når klienten trykker på submit, er følgende:

 

attempt = [Auto Increment]

performed = true/false

username

userAttempt = Antall forsøk pr. bruker.

verdiene sendt fra klient

måleresultat = verdi 0 inntil oppdatert.

 

Hvordan kan jeg fra et php-script kjøre igang en cpp-fil på en annen pc i nettverket, og i tillegg få dette programmet til å ta imot "username", "userAttempt" og verdiene sendt fra klienten som brukeren har tastet inn?

 

Vedlagt bilde illustrerer kanskje bedre oppsettet mitt hvis noe er uklart. Rød strek er slik jeg har forstått hvordan alternativet kan være, som foreslått av etse.

 

Klientene skriver inn en webaddresse og får da opp en nettside i php. Webserveren og MySQL skal være på samme pc. Idag er Webserver og MySQL lagret i RaspberryPi, men planen er å skille ut denne. Det er på Raspberry Pi at c++ programmet som skal kjøres ligger. Det programmet gjør (idag) er å hente første uoppdaterte linje fra databasen (første med performed = 0), sende verdiene av disse til FPGA via et serielt interface på RPi. Når FPGA'en deretter har gjort målinger vil den sende data tilbake til RPi, og når disse er mottatt vil c++ programmet oppdatere den aktuelle raden i databasen med gjeldende verdi.

 

Ajax/jQuery er implementert slik at Klienten mottar resultatet øyeblikkelig.

post-79688-0-38339300-1394626093_thumb.png

Endret av r2d290
Lenke til kommentar

Hva om C++-programmet har en åpen connection mot et nettverk, og dermed alltid kjører? Her driver du å lytter etter nye tilkoblinger over nettverket. Når du ønsker å sende data til den lar du PHP-scriptet ditt koble til C++ programmet overnettverk og sender dataen enten via et REST-interface eller som f.eks. JSON.

 

Dette krever selvfølgelig litt kunskaper om hvordan du programmerer nettverk i C++. Om dette er noe du synes er vanskelig kan du f.eks. sette opp en enkel REST-server (som du kan skrive i PHP, python, ruby - eller hvilket som helst annet scriptespråk du liker). Denne kan ta ta i mot selve nettverkstilkoblingen og starte opp C++ applikasjonen og sende dataen til programmet via stdin.

 

Om RapsberryPi har et REST-interface som støtter HTTP-trafikk, så kan du bare bruke "file_get_contents()" i PHP for å sende data over.

Endret av etse
Lenke til kommentar

Tusen takk!!! :)

 

Jeg har foreløpig gått for den første løsningen din, med å sove i 1 sekund, og gå gjennom alle nye oppdateringer hvis det har kommet noen. Har testet det, og ser igrunn ut til å fungere greit. Skal drøfte det med veilederen min, og hvis han mener det er nødvendig å med en bedre løsning så skal jeg se litt nærmere på det siste du har skrevet.

 

Takk til nå.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...