yeah but for some reason I have/had assumed the ISR sets a flag to call the functions that I write, I didnt think it was calling it directly, hence putting alot of code in there was ok.....
The thing that generates the interrupt sets a flag that says that an interrupt (of a specific type) occurred. At the soonest opportunity, the highest priority interrupt is handled (not all interrupts are the same priority). Handling the interrupt means calling whatever ISR is registered to handle the specific interrupt.
That could include nothing (pin 2 goes HIGH but there is no RISING interrupt handler registered) or some system defined code (pin 0 goes HIGH indicating serial data is arriving) or some user defined code (pin 2 goes LOW and attachInterrupt() was used to register a handler for the FALLING event).
So, your ISR IS called, somewhat indirectly, when an interrupt occurs. There are plenty of interrupts that can happen - the clock ticking, serial data arriving, pins 2 or 3 (in the non-Mega varieties) going HIGH or LOW - and the system needs to be able to handle all of them before data gets lost. That is why an ISR needs to be fast.
Further interrupts are disabled while an ISR is running. This is why delay() can't be used in an ISR, since it relies in the clock ticking to know when to end, and the clock doesn't tick during your ISR. Serial data transmission also relies on interrupts which is why serial data doesn't get sent during an ISR. When the ISR returns, interrupts are enabled again.
Setting a flag in the ISR is the proper approach, but that means that the loop() function, or anything it calls, needs to check the flag often.
Since this is the case, interrupt handling is not as useful as a lot of people seem to think. For instance, attaching an interrupt handler to pin 2 will let your sketch know immediately if the switch attached to that pin is pressed or released.
The ISR then sets a flag to remember that this occurred.
Meanwhile, loop() called a function that contains delay(1200000UL). The fact that the flag is set is not going to be noticed for some (possibly quite long) period of time.
Once the delay ends, the sketch can then note that while it was taking a nap the switch was pressed. However, you can see that the action that the user expected when pushing the button is still delayed.
It's generally much better to write code that polls the switch often enough that interrupts are not needed. Of course, this means not using delay() and restructuring your program, but it makes your program react much more quickly to user/external input.